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

Posted jffx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树相关的知识,希望对你有一定的参考价值。

 技术分享图片


写了一点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 }

 

 

 


以上是关于(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树的主要内容,如果未能解决你的问题,请参考以下文章

哈弗曼树与哈夫曼编码

求哈弗曼树的编码

求哈弗曼树的编码

哈弗曼树及其操作

Java---Huffman树的实现

B树和B+树