- 过程概述
- 创建一个二叉排序树
- 插入24个随机数据
- 输出前序遍历
- 输出中序遍历
- 输出后序遍历
- 搜索一个给定的节点是否在树中
- 计算二叉排序树的节点数
- 计算所有叶子节点的深度的总和
- 计算二叉排序树的叶子数
- 计算所有叶子节点的平均深度
- 计算二叉排序树的高度(最大的叶子节点的深度)
- 代码清单
- BSTNode.java // 二叉排序树节点
1 public class BSTNode { 2 3 int item; // The data in this node. 4 BSTNode left, right; // Pointer to subtree. 5 6 public BSTNode(int el) { 7 this(el, null, null); 8 } 9 10 public BSTNode(int el, BSTNode left, BSTNode rigth) { 11 this.item = el; 12 this.left = left; 13 this.right = rigth; 14 } 15 16 }
- BST.java // 二叉排序树
1 public class BST { 2 3 BSTNode root; // Pointer to the root node in the tree. 4 5 void insert(int x) { 6 root = insert(x, root); 7 } 8 9 private BSTNode insert(int x, BSTNode t) { 10 if (t == null) // The tree is empty 11 return new BSTNode(x); 12 if (x < t.item) 13 t.left = insert(x, t.left); 14 else if (x >= t.item) 15 t.right = insert(x, t.right); 16 return t; 17 } 18 19 void visit(BSTNode p) { 20 System.out.print(p.item + " "); 21 } 22 23 void preorder() { 24 preorder(root); 25 } 26 27 void inorder() { 28 inorder(root); 29 } 30 31 void postorder() { 32 postorder(root); 33 } 34 35 private void preorder(BSTNode p) { 36 if (p != null) { 37 visit(p); 38 preorder(p.left); 39 preorder(p.right); 40 } 41 } 42 43 private void inorder(BSTNode p) { 44 if (p != null) { 45 preorder(p.left); 46 visit(p); 47 preorder(p.right); 48 } 49 } 50 51 private void postorder(BSTNode p) { 52 if (p != null) { 53 preorder(p.left); 54 preorder(p.right); 55 visit(p); 56 } 57 } 58 59 /** 60 * Count the nodes in the binary tree to which root points, 61 * and return the answer. If root is null, the answer is zero. 62 */ 63 static int countNodes(BSTNode root) { 64 if (root == null) 65 return 0; // The tree is empty. It contains no nodes. 66 else 67 return countNodes(root.left) + countNodes(root.right) + 1; 68 } 69 70 // Return the number of leaves in the tree to which node points. 71 static int countLeaves(BSTNode node) { 72 if (node == null) 73 return 0; // An empty tree has no leaves. 74 else if (node.left == null && node.right == null) 75 return 1; // Node is a leaf. 76 else 77 return countLeaves(node.left) + countLeaves(node.right); 78 } 79 80 /** 81 * Return true if item is one of the items in the binary sort tree 82 * to which root points. Return false if not. 83 */ 84 static boolean contains(BSTNode node, int item) { 85 while (true) { 86 if (node == null) 87 return false; // Tree is empty, it doesn't contain item. 88 if (item == node.item) 89 return true; // found the item. 90 if (item < node.item) 91 node = node.left; // advance the runner down one level to the left. 92 else 93 node = node.right; // advance the runner down one level to the right. 94 } 95 } 96 97 static int sumDeps(BSTNode node, int dep) { 98 if (node == null) 99 return 0; // The tree is empty, return 0. 100 else if (node.left == null && node.right == null) 101 return dep; // The node is a leaf, return the depth of this node. 102 else 103 return sumDeps(node.left, dep+1) + sumDeps(node.right, dep+1); 104 } 105 106 static int maxLeafDep(BSTNode node, int dep) { 107 if (node == null) 108 return 0; // The tree is empty, return 0. 109 else if (node.left == null && node.right == null) 110 return dep; // The node is a leaf, return the depth of this node. 111 else 112 return Math.max(maxLeafDep(node.left, dep+1), maxLeafDep(node.right, dep+1)); 113 } 114 115 }
- Main.java // 主程序
1 //Makes the random tree and prints the statistics. 2 3 import java.util.Random; 4 5 public class Main { 6 public static void main(String[] args) { 7 BST t = new BST(); 8 Random random = new Random(); 9 int n = 24; 10 for (int i = 0; i < n; i++) 11 t.insert(random.nextInt(n) + 1); 12 t.preorder(); 13 System.out.println(" preorder"); 14 t.inorder(); 15 System.out.println(" inorder"); 16 t.postorder(); 17 System.out.println(" postorder"); 18 System.out.println("contains(" + n + ")?:" + BST.contains(t.root, n)); 19 System.out.println("Nodes(root):" + BST.countNodes(t.root)); 20 int sum_dep = BST.sumDeps(t.root, 0), 21 leaves = BST.countLeaves(t.root); 22 System.out.println("sumDeps(root):" + sum_dep); 23 System.out.println("leaves(root):" + leaves); 24 System.out.println("avgDep(sumDeps/leaves):" + (double)sum_dep / leaves); 25 System.out.println("maxDep(root):" + BST.maxLeafDep(t.root, 0)); 26 } 27 }
- BSTNode.java // 二叉排序树节点
- 输出结果
9 2 2 4 2 7 4 6 8 10 9 20 10 17 16 10 15 10 15 19 20 24 20 21 preorder
2 2 4 2 7 4 6 8 9 10 9 20 10 17 16 10 15 10 15 19 20 24 20 21 inorder
2 2 4 2 7 4 6 8 10 9 20 10 17 16 10 15 10 15 19 20 24 20 21 9 postorder
contains(24)?:true
Nodes(root):24
sumDeps(root):44
leaves(root):8
avgDep(sumDeps/leaves):5.5
maxDep(root):8 - 分析报告
上面为了方便演示遍历,n只设到了24,为了测试裸二叉排序树在随机数据下的平衡情况,24太小肯定不够,我把n设到1024再把程序跑N次,发现树的叶子节点的平均深度约为12,高于完全二叉树的9,高出1/3,最大深度约为20。二叉排序树在平均情况下运行时间为O(logN),在最坏的情况下(递增或递减的数据)会退化为一条链表,运行时间为O(N)。可以在插入数据时调整节点位置让二叉排序树保持平衡(比如AVL树……),保证平均和最坏情况下运行时间为O(logN)。