相关概念
存储结构:
- 顺序存储结构:二叉树的顺序存储结构适用于完全二叉树,对完全二叉树进行顺序编号,通过二叉树的性质五(第1个结点为根结点,第i个结点的左孩子为第2i个结点,右孩子为第2i+1个结点)。
- 链式存储结构:一般情况下,采用链式存储结构来存储二叉树。每个结点有3个域:data、left、right。
遍历:
- 先根次序:根->左->右。
- 中根次序:左->根->右。
- 后根次序:左->右->根。
遍历算法:
- 递归
- 非递归:通过设立一个栈。
声明二叉树结点类
1 /** 2 * Copyright 2016 Zhengbin‘s Studio. 3 * All right reserved. 4 * 2016年7月16日 上午8:19:15 5 */ 6 package Two; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class TreeNode { 13 int val; 14 TreeNode left; 15 TreeNode right; 16 TreeNode(int x) { 17 val = x; 18 } 19 /** 20 * 先根遍历 21 * @param p 22 */ 23 public void preorder(TreeNode p) { 24 if(p != null) { 25 System.out.print(p.val + " "); 26 preorder(p.left); 27 preorder(p.right); 28 } 29 } 30 /** 31 * 中根遍历 32 * @param p 33 */ 34 public void inorder(TreeNode p) { 35 if(p != null) { 36 preorder(p.left); 37 System.out.print(p.val + " "); 38 preorder(p.right); 39 } 40 } 41 /** 42 * 后根遍历 43 * @param p 44 */ 45 public void postorder(TreeNode p) { 46 if(p != null) { 47 preorder(p.left); 48 preorder(p.right); 49 System.out.print(p.val + " "); 50 } 51 } 52 }
声明二叉树类 和 由先根遍历与中根遍历构造二叉树
建立一颗二叉树必须明确以下两点:
- 结点与双亲结点及孩子结点间的层次关系。
- 兄弟结点间的左右子树的顺序关系。
先根次序或后根次序反映双亲与孩子结点的层次关系,中根次序反映兄弟结点间的左右次序。所以,已知先根和中根两种遍历序列,或中根和后根两种遍历序列才能够唯一确定一颗二叉树。而已知先根和后根两种遍历序列仍无法唯一确定一颗二叉树。
1 /** 2 * Copyright 2016 Zhengbin‘s Studio. 3 * All right reserved. 4 * 2016年7月16日 上午9:30:01 5 */ 6 package Two; 7 8 import java.util.Arrays; 9 10 /** 11 * @author zhengbinMac 12 * 13 */ 14 public class Tree { 15 protected TreeNode root; 16 public Tree() { 17 root = null; 18 } 19 public Tree(int[] pre, int[] in) { 20 // root = reConstructBinaryTree(pre, in); 21 root = reConstructBinaryTree1(pre, in); 22 } 23 /** 24 * 先根次序 25 */ 26 public void preorderTraversal() { 27 System.out.println("先根次序遍历:"); 28 if(root != null) { 29 root.preorder(root); 30 } 31 } 32 /** 33 * 中根次序 34 */ 35 public void inorderTraversal() { 36 System.out.println("中根次序遍历:"); 37 if(root != null) { 38 root.inorder(root); 39 } 40 } 41 /** 42 * 后根次序 43 */ 44 public void postorderTraversal() { 45 System.out.println("后根次序遍历:"); 46 if(root != null) { 47 root.postorder(root); 48 } 49 } 50 /** 51 * 通过先根遍历与中根遍历构造二叉树(1) 52 */ 53 public TreeNode reConstructBinaryTree1(int[] pre, int[] in) { 54 if(pre.length == 0 || in.length == 0) { 55 return null; 56 } 57 TreeNode p = new TreeNode(pre[0]); 58 for (int i = 0; i < in.length; i++) { 59 if(pre[0] == in[i]) { 60 p.left = reConstructBinaryTree1(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i)); 61 p.right = reConstructBinaryTree1(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1, in.length)); 62 } 63 } 64 return p; 65 } 66 /** 67 * 通过先根遍历与中根遍历构造二叉树(2) 68 */ 69 public TreeNode reConstructBinaryTree(int[] pre, int[] in) { 70 if(pre == null || in == null) { 71 return null; 72 } 73 TreeNode p = null; 74 int first; 75 int n = pre.length; 76 int k = 0; 77 if(n > 0) { 78 // 取第一个为根 79 first = pre[0]; 80 p = new TreeNode(first); 81 // 确定根结点在中根序列中的位置 82 for (int i = 0; i < in.length; i++) { 83 if(in[i] == first) { 84 k = i; 85 break; 86 } 87 } 88 // 左子树 89 int[] presubLeft = new int[k]; 90 int[] insubLeft = new int[k]; 91 // 先根 92 for (int i = 1, j = 0; i <= k; i++, j++) { 93 presubLeft[j] = pre[i]; 94 } 95 // 中根 96 for (int i = 0, j = 0; i <= k-1; i++, j ++) { 97 insubLeft[j] = in[i]; 98 } 99 p.left = reConstructBinaryTree(presubLeft, insubLeft); 100 // 右子树 101 int[] presubRight = new int[n-1-k]; 102 int[] insubRight = new int[n-1-k]; 103 // 先根 104 for (int i = k+1, j = 0; i <= n-1; i++,j++) { 105 presubRight[j] = pre[i]; 106 } 107 // 中根 108 for (int i = k+1, j = 0; i <= n-1; i++,j++) { 109 insubRight[j] = in[i]; 110 } 111 p.right = reConstructBinaryTree(presubRight, insubRight); 112 } 113 return p; 114 } 115 }
测试类
1 /** 2 * Copyright 2016 Zhengbin‘s Studio. 3 * All right reserved. 4 * 2016年7月16日 上午9:27:40 5 */ 6 package Two; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class Test { 13 14 public static void main(String[] args) { 15 int[] pre = {1,2,4,3,5,6}; 16 int[] in = {4,2,1,5,3,6}; 17 Tree t = new Tree(pre, in); 18 t.inorderTraversal(); 19 System.out.println(); 20 t.postorderTraversal(); 21 System.out.println(); 22 t.preorderTraversal(); 23 } 24 }
在线编程:
时间: 2024-10-10 14:14:33