其中包含有先序遍歷、中序遍歷、后序遍歷以及廣度優先遍歷四種遍歷樹的方法:
1 package com.ietree.basic.datastructure.tree.binarytree; 2 3 import java.util.ArrayDeque; 4 import java.util.ArrayList; 5 import java.util.List; 6 import java.util.Queue; 7 8 /** 9 * Created by ietree 10 * 2017/5/1 11 */ 12 public class ThreeLinkBinTree<E> { 13 14 public static class TreeNode { 15 16 Object data; 17 TreeNode left; 18 TreeNode right; 19 TreeNode parent; 20 21 public TreeNode() { 22 23 } 24 25 public TreeNode(Object data) { 26 this.data = data; 27 } 28 29 public TreeNode(Object data, TreeNode left, TreeNode right, TreeNode parent) { 30 this.data = data; 31 this.left = left; 32 this.right = right; 33 this.parent = parent; 34 } 35 36 } 37 38 private TreeNode root; 39 40 // 以默認的構造器創建二叉樹 41 public ThreeLinkBinTree() { 42 this.root = new TreeNode(); 43 } 44 45 // 以指定根元素創建二叉樹 46 public ThreeLinkBinTree(E data) { 47 this.root = new TreeNode(data); 48 } 49 50 /** 51 * 為指定節點添加子節點 52 * 53 * @param parent 需要添加子節點的父節點的索引 54 * @param data 新子節點的數據 55 * @param isLeft 是否為左節點 56 * @return 新增的節點 57 */ 58 public TreeNode addNode(TreeNode parent, E data, boolean isLeft) { 59 60 if (parent == null) { 61 throw new RuntimeException(parent + "節點為null, 無法添加子節點"); 62 } 63 if (isLeft && parent.left != null) { 64 throw new RuntimeException(parent + "節點已有左子節點,無法添加左子節點"); 65 } 66 if (!isLeft && parent.right != null) { 67 throw new RuntimeException(parent + "節點已有右子節點,無法添加右子節點"); 68 } 69 70 TreeNode newNode = new TreeNode(data); 71 if (isLeft) { 72 // 讓父節點的left引用指向新節點 73 parent.left = newNode; 74 } else { 75 // 讓父節點的left引用指向新節點 76 parent.right = newNode; 77 } 78 // 讓新節點的parent引用到parent節點 79 newNode.parent = parent; 80 return newNode; 81 } 82 83 // 判斷二叉樹是否為空 84 public boolean empty() { 85 // 根據元素判斷二叉樹是否為空 86 return root.data == null; 87 } 88 89 // 返回根節點 90 public TreeNode root() { 91 if (empty()) { 92 throw new RuntimeException("樹為空,無法訪問根節點"); 93 } 94 return root; 95 } 96 97 // 返回指定節點(非根節點)的父節點 98 public E parent(TreeNode node) { 99 if (node == null) { 100 throw new RuntimeException("節點為null,無法訪問其父節點"); 101 } 102 return (E) node.parent.data; 103 } 104 105 // 返回指定節點(非葉子)的左子節點,當左子節點不存在時返回null 106 public E leftChild(TreeNode parent) { 107 if (parent == null) { 108 throw new RuntimeException(parent + "節點為null,無法添加子節點"); 109 } 110 return parent.left == null ? null : (E) parent.left.data; 111 } 112 113 // 返回指定節點(非葉子)的右子節點,當右子節點不存在時返回null 114 public E rightChild(TreeNode parent) { 115 if (parent == null) { 116 throw new RuntimeException(parent + "節點為null,無法添加子節點"); 117 } 118 return parent.right == null ? null : (E) parent.right.data; 119 } 120 121 // 返回該二叉樹的深度 122 public int deep() { 123 // 獲取該樹的深度 124 return deep(root); 125 } 126 127 // 這是一個遞歸方法:每一棵子樹的深度為其所有子樹的最大深度 + 1 128 private int deep(TreeNode node) { 129 if (node == null) { 130 return 0; 131 } 132 // 沒有子樹 133 if (node.left == null && node.right == null) { 134 return 1; 135 } else { 136 int leftDeep = deep(node.left); 137 int rightDeep = deep(node.right); 138 // 記錄其所有左、右子樹中較大的深度 139 int max = leftDeep > rightDeep ? leftDeep : rightDeep; 140 // 返回其左右子樹中較大的深度 + 1 141 return max + 1; 142 } 143 } 144 145 // 實現先序遍歷 146 // 1、訪問根節點 147 // 2、遞歸遍歷左子樹 148 // 3、遞歸遍歷右子樹 149 public List<TreeNode> preIterator() { 150 return preIterator(root); 151 } 152 153 private List<TreeNode> preIterator(TreeNode node) { 154 155 List<TreeNode> list = new ArrayList<TreeNode>(); 156 // 處理根節點 157 list.add(node); 158 159 // 遞歸處理左子樹 160 if (node.left != null) { 161 list.addAll(preIterator(node.left)); 162 } 163 164 // 遞歸處理右子樹 165 if (node.right != null) { 166 list.addAll(preIterator(node.right)); 167 } 168 169 return list; 170 171 } 172 173 // 實現中序遍歷 174 // 1、遞歸遍歷左子樹 175 // 2、訪問根節點 176 // 3、遞歸遍歷右子樹 177 public List<TreeNode> inIterator() { 178 return inIterator(root); 179 } 180 181 private List<TreeNode> inIterator(TreeNode node) { 182 183 List<TreeNode> list = new ArrayList<TreeNode>(); 184 185 // 遞歸處理左子樹 186 if (node.left != null) { 187 list.addAll(inIterator(node.left)); 188 } 189 190 // 處理根節點 191 list.add(node); 192 193 // 遞歸處理右子樹 194 if (node.right != null) { 195 list.addAll(inIterator(node.right)); 196 } 197 198 return list; 199 200 } 201 202 // 實現后序遍歷 203 // 1、遞歸遍歷左子樹 204 // 2、遞歸遍歷右子樹 205 // 3、訪問根節點 206 public List<TreeNode> postIterator() { 207 return postIterator(root); 208 } 209 210 private List<TreeNode> postIterator(TreeNode node) { 211 212 List<TreeNode> list = new ArrayList<TreeNode>(); 213 214 // 遞歸處理左子樹 215 if (node.left != null) { 216 list.addAll(postIterator(node.left)); 217 } 218 219 // 遞歸處理右子樹 220 if (node.right != null) { 221 list.addAll(postIterator(node.right)); 222 } 223 224 // 處理根節點 225 list.add(node); 226 227 return list; 228 229 } 230 231 // 實現廣度優先遍歷 232 // 廣度優先遍歷又稱為按層遍歷,整個遍歷算法先遍歷二叉樹的第一層(根節點),再遍歷根節點的兩個子節點(第二層),以此類推 233 public List<TreeNode> breadthFirst() { 234 235 Queue<TreeNode> queue = new ArrayDeque<TreeNode>(); 236 List<TreeNode> list = new ArrayList<TreeNode>(); 237 if (root != null) { 238 // 將根元素加入“隊列” 239 queue.offer(root); 240 } 241 while (!queue.isEmpty()) { 242 // 將該隊列的“隊尾”的元素添加到List中 243 list.add(queue.peek()); 244 TreeNode p = queue.poll(); 245 // 如果左子節點不為null,將它加入“隊列” 246 if (p.left != null) { 247 queue.offer(p.left); 248 } 249 // 如果右子節點不為null,將它加入“隊列” 250 if (p.right != null) { 251 queue.offer(p.right); 252 } 253 } 254 return list; 255 } 256 257 }