![]()
写了一点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 }