(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树


写了一点haffman树的创建和二叉树的非递归遍历.

  • 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间.
我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符
卧室占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符


  

  1 package cc.algorithms;
  2
  3 import java.util.ArrayList;
  4 import java.util.LinkedList;
  5 import java.util.List;
  6
  7 public class HaffManTree<E> {
  8     private Node<E> root ;
  9     public static class Node<E> {
 10         E data ;
 11         double weight ;
 12         Node<E> left, right;
 13         Node<E> parent ;
 14
 15         public Node() {
 16             this.left = this.right = this.parent = null ;
 17         }
 18         public Node(E data, double weight) {
 19             this.data = data ;
 20             this.weight = weight ;
 21         }
 22
 23         @Override
 24         public String toString() {
 25             if (data == null) {
 26                 return "[data=null, weight=" + this.weight + "]" ;
 27             }
 28             else
 29                 return "[data=" + this.data + ", weight=" + this.weight + "]";
 30         }
 31     }
 32
 33     public static void main(String[] args) {
 34         List<Node<String>> nodes = new ArrayList<>() ;
 35         nodes.add(new Node("A", 99)) ;
 36         nodes.add(new Node("B", 21)) ;
 37         nodes.add(new Node("C", 211)) ;
 38         nodes.add(new Node("D", 26)) ;
 39         nodes.add(new Node("E", 24)) ;
 40         nodes.add(new Node("F", 23)) ;
 41
 42         HaffManTree<String> hf = new HaffManTree() ;
 43         hf.create(nodes) ;
 44         System.out.println("前序:") ;
 45         hf.prefByStack(); ;
 46         System.out.println("中序");
 47         hf.inByStack() ;
 48         System.out.println("后序:");
 49         hf.hostByStack() ;
 50         System.out.println("层序");
 51         hf.floorByQueen() ;
 52     }
 53
 54
 55     /**
 56      * 创建haffman树
 57      */
 58     public void create(List<Node<E>> nodes) {
 59         //只要列表中有2个以上的节点
 60         while(nodes.size() > 1) {
 61             shellSort(nodes);
 62
 63             Node<E> min1 = nodes.get(nodes.size() - 1) ;
 64             Node<E> min2 = nodes.get(nodes.size() - 2) ;
 65
 66             //生成父节点
 67             Node<E> parent = new Node(null, min1.weight + min2.weight) ;
 68
 69             parent.left = min1 ;
 70             parent.right = min2 ;
 71             min1.parent = parent;
 72             min2.parent = parent ;
 73             //从列表中删除两个最小节点
 74             nodes.remove(nodes.size() - 1) ;
 75             nodes.remove(nodes.size() - 1);
 76
 77             nodes.add(parent) ;
 78         }
 79         this.root =  nodes.get(0) ;
 80     }
 81
 82     /**
 83      * 希尔排序--从大到小排序
 84      */
 85     public void shellSort(List<Node<E>> nodes) {
 86         int N = nodes.size() ;
 87         int h = 1 ;
 88         while(h < N / 3) h = 3 * h + 1 ;
 89         while(h >= 1) {
 90             for(int i = h ; i < N ; ++i) {
 91                 for(int j = i ;
 92                     j >= h && nodes.get(j).weight > nodes.get(j - h).weight ;
 93                     j -= h) {
 94                     Node temp = nodes.get(j) ;
 95                     nodes.set(j, nodes.get(j - h)) ;
 96                     nodes.set(j - h, temp) ;
 97                 }
 98             }
 99             h /= 3 ;
100         }
101         for(Node<E> x : nodes) {
102             System.out.println(x);
103         }
104         System.out.println("*********************************") ;
105     }
106     /**
107      * 前序遍历 --------- 递归
108      */
109     public void pre() {
110         System.out.println(this.root) ;
111         prefOrder(this.root);
112     }
113     private void prefOrder(Node<E> node) {
114         if(node != null) {
115             System.out.println(node) ;
116             prefOrder(node.left);
117             prefOrder(node.right);
118         }
119     }
120     public void prefByStack() {
121         ArrayList<Node<E>> st = new ArrayList<>() ;
122         Node<E> p = this.root ;
123
124         while(p != null || !st.isEmpty()) {
125             while(p != null) {
126                 System.out.println(p) ;
127                 st.add(p) ;
128                 p = p.left ;
129             }
130             if(!st.isEmpty()) {
131                 p = st.remove(st.size() - 1) ;
132                 p = p.right ;
133             }
134         }
135     }
136     public void inByStack() {
137         ArrayList<Node<E>> st = new ArrayList<>() ;
138         Node<E> p = this.root ;
139
140         while(p != null || !st.isEmpty()) {        //站不空,或者当前节点不空
141             while(p != null) {
142                 st.add(p) ;
143                 p = p.left ;
144             }
145             if(!st.isEmpty()) {                //pop,并访问,然后换右子树
146                 p = st.remove(st.size() - 1) ;
147                 System.out.println(p) ;
148                 p = p.right ;
149             }
150         }
151     }
152     //需要判断右子树是否访问过
153     public void hostByStack() {
154         ArrayList<Node<E>> st = new ArrayList<>() ;
155         Node<E> p = this.root ;
156         Node<E> pre = null ;
157
158         while(p != null || !st.isEmpty()) {
159             while(p != null) {
160                 st.add(p) ;
161                 p = p.left ;
162             }
163             if(!st.isEmpty()) {
164                 //查看栈顶元素,判断右子树是否访问过<br>
165                 //访问过,就访问当前节点<br>
166                 //否则,访问右子树
167                 p = st.get(st.size() - 1) ;
168                 if(p.right == null || p.right == pre) {
169                     p = st.remove(st.size() - 1) ;
170                     System.out.println(p) ;
171                     //更新
172                     pre = p ;
173                     p = null ;
174                 } else {
175                     p = p.right ;
176                 }
177             }
178         }
179     }
180
181     /**
182      * 总结:
183      *  1.前序,第一次碰到节点的时候访问<br>
184      *  2.中序,第二次碰到节点的时候访问,<br>
185      *  3.后序,第三次碰到节点的时候访问<br>
186      */
187
188
189     //层次遍历---即广度优先遍历
190     public void floorByQueen() {
191         LinkedList<Node<E>> queue = new LinkedList<>() ;
192         Node<E> p = this.root ;
193         //将根入队
194         if(p != null) {
195             queue.addLast(p); ;
196             while(!queue.isEmpty()) {
197                 p = queue.removeFirst() ;
198                 System.out.println(p) ;
199                 //将左右子树加入队列中
200                 if(p.left != null) {
201                     queue.addLast(p.left);
202                 }
203                 if(p.right != null) {
204                     queue.addLast(p.right) ;
205                 }
206             }
207         }
208     }
209 }


(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

原文地址:https://www.cnblogs.com/jffx/p/9896316.html

时间: 2024-08-10 19:26:19

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树的相关文章

Cordova Android源码分析系列二(CordovaWebView相关类分析)

本篇文章是Cordova Android源码分析系列文章的第二篇,主要分析CordovaWebView和CordovaWebViewClient类,通过分析代码可以知道Web网页加载的过程,错误出来,多线程处理等. CordovaWebView类分析 CordovaWebView类继承了Android WebView类,这是一个很自然的实现,共1000多行代码.包含了PluginManager pluginManager,BroadcastReceiver receiver,CordovaInt

Spring5源码分析之启动类的相关接口和注解

一些基础但是核心的知识总结: Spring Boot项目启动的时候需要加@Configuration. @ComponentScan @Configuration  + @Bean  把第三方jar包注入到容器中. 内部的直接 @Service @Controller等等之类配合 @ComponentSscan 的就OK了 @Scope可以实现单例 对于启动默认是饿汉式调用时候创建(但是项目启动时候比较耗费时间),另外一种是调用时候创建 @ComponentScan有排除的用法,排除那个组件 

leveldb 源码阅读,细节记录memberTable

leveldb 是看着前辈们的大概分析,然后看着源码,将自己的疑惑和解决记录下来: Leveldb源码分析 从memberTable插入一条记录和查找一条记录从上而下分析 插入: 插入的函数 void MemTable::Add(SequenceNumber s, ValueType type,const Slice& key,const Slice& value) 参数: SequenceNumber    插入的序号,在skiplist里,这个序号是降序列的 ValueType typ

二叉搜索树的实现源码(源码较长,请慎入)

实现二叉搜索树的一种好方法是利用二叉树抽象数据类型. 我们以BisTree这个名称来代表二叉搜索树这种数据结构.通过typedef方式将BisTree(二叉搜索树)实现为BiTree(二叉树)的别名. 采用typedef方法使得二叉搜索树具有了某种程度的多态能力,如同栈和队列一样.这意味着除了专属于二叉搜索树的操作外,还可以在其上执行属于二叉树的操作. 数据结构AvlNode代表树中的结点,AvlNode包含3个成员: data是存储在结点中的数据:hidden用来标识结点是否已经移除:fact

Hadoop源码分析下载、最新最全资料分享

apache_hadoop源码,下载: http://archive.apache.org/dist/ Hadoop 工具下载: http://hadoop.apache.org/ Hadoop大数据最新最全资料下载地址: http://download.csdn.net/album/detail/3047

【数据结构与算法】二叉树递归与非递归遍历(附完整源码)(转)

转自:http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现. 一.三种遍历方式的递

lua.5.2.3源码阅读(01):文件读取相关

Lua在载入lua文件的时候,读取过程中通过cache的方式,默认cache为512字节: 1.cache中包含数据时,直接将cache中数据返回: 2.cache中不包含数据的时候,每次读取512个字节,进行cache: 1 typedef struct LoadF { 2 int n; /* number of pre-read characters */ 3 FILE *f; /* file being read */ 4 char buff[LUAL_BUFFERSIZE]; /* ar

查阅相关资料,回答下列问题 如果你为Liz开发问题账户分析系统,你准备如何进行需求分析,第一步要做什么? 你认为目前需求分析材料中欠缺哪些内容?

.如果我为liz开发问题账户系统时,我第一步会做的是需求的征集与客户进行沟通交流,准确了解和描述客户需求,并能够从客户的语言中帮助用户挖掘需求: 2.材料中还欠缺 a.假是否应该设置一个信用度,如这些问题账户还款完毕,这些人是否会相对原来的信用度会有所下降: b.系统是否拥有多角色登录的管理和各个角色的权限限制: c.系统是否应该有打印或统计的功能: d.系统是否应该有个逾期自动催款的功能. 3.模拟系统原型 功能:能够快速查询客户账户: 能够分析一个客户是否为问题账户: 能够给出一个问题账户的

第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 上一节我们描述了monkey的命令处理入口函数run是如何调用optionProcess方法来解析命令行参数的.启动参数主要时去指导Monkey时怎么运行起来的,但Monkey作为MonkeyRunner框架的一部分,