[关闭]
@lzb1096101803 2016-03-14T13:21:30.000000Z 字数 4945 阅读 485

二叉树遍历

电话面试


  1. package 二叉树.二叉查找树;
  2. import java.util.LinkedList;
  3. public class BinaryTree<V extends Comparable<V>> {
  4. private Node root;
  5. public BinaryTree() {
  6. root = new Node();
  7. }
  8. /**
  9. * 数组构造器 ,无一定规则,只能按层次构造
  10. * 1
  11. * 2 3
  12. * 4 5 6 7
  13. * 8
  14. * 9
  15. * 构成上面的形状
  16. */
  17. public BinaryTree(V[] values) {
  18. System.out.print("新建binaryTree:");
  19. for (V i : values) {
  20. System.out.print(i + " ");
  21. }
  22. System.out.println();
  23. boolean isLeft = true;
  24. int len = values.length;
  25. if (len == 0)
  26. return ;
  27. LinkedList<Node> queue = new LinkedList<Node>();
  28. root = new Node(values[0]); //先构造根节点(第一个元素)
  29. queue.addLast(root); //将第一个元素添加到链表中,链表头结点始终是父节点
  30. Node parent = null;
  31. Node current = null;
  32. for (int i=1; i<len; i++) {
  33. current = new Node(values[i]);
  34. queue.addLast(current); //加入第二个元素 1->2
  35. if (isLeft)
  36. parent = queue.getFirst(); //无论插入左孩子还是右孩子,都是获取链表第一个元素
  37. else //只是说插入左孩子,下次插入元素的父节点还是第一个元素本身,
  38. parent = queue.removeFirst(); //如果插入右孩子,说明下次插入的元素需要父节点更换成链表第二个元素,所以移除原来第一个元素1,让第二个元素2变为链表头
  39. if (isLeft) {
  40. parent.leftChild = current; //如果需要插入左孩子,就设置左孩子
  41. isLeft = false; //下次插入是不再插入左孩子
  42. }else {
  43. parent.rightChild = current; //插入右孩子
  44. isLeft = true; //下次插入左孩子,此时父节点不再是1
  45. }
  46. }
  47. }
  48. /**
  49. * 递归先序遍历
  50. */
  51. public void preorder() {
  52. System.out.print("binaryTree递归先序遍历:");
  53. preorderTraverseRecursion(root);
  54. System.out.println();
  55. }
  56. private void preorderTraverseRecursion(Node node){
  57. System.out.print(node.element+" ");
  58. if (node.leftChild != null)
  59. preorderTraverseRecursion (node.leftChild);
  60. if (node.rightChild != null)
  61. preorderTraverseRecursion (node.rightChild);
  62. }
  63. /**
  64. * 递归中序遍历
  65. */
  66. public void inorder() {
  67. System.out.print("binaryTree递归中序遍历:");
  68. inorderTraverseRecursion(root);
  69. System.out.println();
  70. }
  71. private void inorderTraverseRecursion(Node node) {
  72. if (node.leftChild != null)
  73. inorderTraverseRecursion(node.leftChild);
  74. System.out.print(node.element+" ");
  75. if (node.rightChild != null)
  76. inorderTraverseRecursion(node.rightChild);
  77. }
  78. /**
  79. * 递归后序遍历
  80. */
  81. public void postorder() {
  82. System.out.print("binaryTree递归后序遍历:");
  83. postorderTraverseRecursion(root);
  84. System.out.println();
  85. }
  86. private void postorderTraverseRecursion(Node node) {
  87. if (node.leftChild != null)
  88. inorderTraverseRecursion(node.leftChild);
  89. if (node.rightChild != null)
  90. inorderTraverseRecursion(node.rightChild);
  91. System.out.print(node.element+" ");
  92. }
  93. /**
  94. * 层次遍历
  95. */
  96. public void layerorder() {
  97. System.out.print("binaryTree层次遍历:");
  98. LinkedList<Node> queue = new LinkedList<Node>();
  99. queue.addLast(root);
  100. Node current = null;
  101. while(!queue.isEmpty()) {
  102. current = queue.removeFirst();
  103. if (current.leftChild != null)
  104. queue.addLast(current.leftChild);
  105. if (current.rightChild != null)
  106. queue.addLast(current.rightChild);
  107. System.out.print(current.element+" ");
  108. }
  109. System.out.println();
  110. }
  111. /**
  112. * 非递归先序遍历
  113. * 1
  114. * 2 3
  115. * 4 5 6 7
  116. *
  117. */
  118. public void preorderNoRecursion() {
  119. System.out.print("binaryTree非递归先序遍历:"); //用栈的思维去遍历
  120. LinkedList<Node> stack = new LinkedList<Node>();
  121. stack.push(root); //1
  122. Node current = null;
  123. while (!stack.isEmpty()) {
  124. current = stack.pop(); //current=1 //current=2(1 2)弹出2并访问 //current=4(1 2 4)
  125. System.out.print(current.element+" ");
  126. if (current.rightChild != null) //1 3 //1 3 5
  127. stack.push(current.rightChild);
  128. if (current.leftChild != null) //1 3 2 //1 3 5 4
  129. stack.push(current.leftChild);
  130. }
  131. System.out.println();
  132. }
  133. /**
  134. * 非递归中序遍历
  135. * 栈内保存将要访问的元素
  136. */
  137. public void inorderNoRecursion() {
  138. System.out.print("binaryTree非递归中序遍历:");
  139. LinkedList<Node> stack = new LinkedList<Node>();
  140. Node current = root;
  141. while (current != null || !stack.isEmpty()) {
  142. while(current != null) { //左边有孩子就push
  143. stack.push(current);
  144. current = current.leftChild;
  145. }
  146. if (!stack.isEmpty()) {
  147. current = stack.pop();
  148. System.out.print(current.element+" "); //8
  149. current = current.rightChild; //将当前节点转至右孩子,如果是叶子节点,就为空,上面的内层while不执行,直接Pop出4,输出4,获取4的右节点
  150. }
  151. }
  152. System.out.println();
  153. }
  154. /**
  155. * 非递归后序遍历
  156. * 当上一个访问的结点是右孩子或者当前结点没有右孩子则访问当前结点
  157. */
  158. /**
  159. * 数组构造器
  160. * 1
  161. * 2 3
  162. * 4 5 6 7
  163. * 8
  164. * 构成上面的形状
  165. */
  166. public void postorderNoRecursion() {
  167. System.out.print("binaryTree非递归后序遍历:");
  168. Node rNode = null;
  169. Node current = root;
  170. LinkedList<Node> stack = new LinkedList<Node>();
  171. while(current != null || !stack.isEmpty()) {
  172. while(current != null) {
  173. stack.push(current);
  174. current = current.leftChild;
  175. }
  176. current = stack.pop();
  177. while (current != null && (current.rightChild == null || current.rightChild == rNode)) {
  178. //current.getRightChild() == null保证最左端8的没有右孩子,否则先是输出右孩子
  179. //current.getRightChild() == rNode 应对下面的情况,current是2时,rNode是5,此时要输出2了,因为5已经输出过了
  180. // 2
  181. // 4 5
  182. System.out.print(current.element+" ");
  183. rNode = current;
  184. if (stack.isEmpty()){
  185. System.out.println();
  186. return;
  187. }
  188. current = stack.pop();
  189. }
  190. stack.push(current);
  191. current = current.rightChild;
  192. }
  193. }
  194. public void destroy(){
  195. System.out.println("销毁二叉树");
  196. destroy(root);
  197. }
  198. /**
  199. * 获得二叉树深度
  200. * @return
  201. */
  202. public int getDepth() {
  203. return getDepthRecursion(root);
  204. }
  205. private int getDepthRecursion(Node node){
  206. if (node == null)
  207. return 0;
  208. int llen = getDepthRecursion(node.leftChild);
  209. int rlen = getDepthRecursion(node.rightChild);
  210. int maxlen = Math.max(llen, rlen);
  211. return maxlen + 1;
  212. }
  213. /**
  214. * 销毁二叉树失敗了
  215. */
  216. public void destroy(Node node){
  217. if(node!=null){
  218. destroy(node.leftChild);
  219. destroy(node.rightChild);
  220. node = null;
  221. }
  222. }
  223. class Node{
  224. private V element;
  225. private Node leftChild;
  226. private Node rightChild;
  227. public Node(){
  228. };
  229. public Node(V value) {
  230. element = value;
  231. leftChild = null;
  232. rightChild = null;
  233. }
  234. }
  235. public static void main(String[] args) {
  236. BinaryTree<Integer> bt = new BinaryTree<Integer>(new Integer[]{1,2,3,4,5,6,7});
  237. bt.preorder();
  238. bt.inorder();
  239. bt.postorder();
  240. bt.layerorder();
  241. bt.preorderNoRecursion();
  242. bt.inorderNoRecursion();
  243. bt.postorderNoRecursion();
  244. System.out.println("深度为:" + bt.getDepth());
  245. // bt.destroy();
  246. // bt.layerorder();
  247. }
  248. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注