二叉排序树的高度分析

介绍:

对于二叉排序树而言,其相关操作与树的高度息息相关。设树中有N个节点,

尽管各个操作的平均时间复杂度为O(logN),但当输入的序列有序时,构造出来的树是一个单分支的树,其高度为O(N)

故对二叉排序树的各个操作(如,findMax、contains、findMin...)的时间复杂度也退化成O(N)

现在分析给定一个输入序列,根据该输入序列构造一棵二叉排序树,统计二叉排序树的平均高度。

实现思路如下:

有一个随机生成一组范围为 [1,N] 的随机数生成算法,该算法参考:

然后,以上面生成的一组序列作为树的结点,插入到树中。

插入完成后,计算该树的树高。

二叉排序树高的平均值 = 各棵树的高度之和 / tree_numbers。比如,30棵二叉排序树,每棵有31个节点,树高度的平均值为 8.666666666666666

统计结果如下:

树的数目,               每棵树中节点的数目,      二叉排序树高的平均值                   完全二叉树的高度(根的高度为0)

tree_numbers         node_numbers             averHeight

30                         31                               8.666666666666666                   4

30                         63                               10.833333333333334                 5

30                        127                              13.366666666666667                 6

45                        31                                8.422222222222222                   4

45                        63                                10.822222222222223                 5

45                       127                               13.466666666666667                 6

15                       31                                 8.2                                            4

15                       63                                 11.266666666666667                 5

15                       127                               12.666666666666666                 6

15                       99                                 11.8                                          6

30                       99                                 12.3                                          6

45                       99                                 12.488888888888889                 6

(11.8+12.3+12.49)/3 = 12.19666666

从上面可以看出,对于相同数目节点的二叉排序树和完成二叉树,前者的高度要比后者高一倍。

具体实现代码如下:

 1 import c2.C2_2_8;
 2
 3 public class BinarySearchTree<T extends Comparable<? super T>> {
 4
 5     private static class BinaryNode<T> {
 6         T element;
 7         BinaryNode<T> left;
 8         BinaryNode<T> right;
 9
10         public BinaryNode(T element) {
11             this(element, null, null);
12         }
13
14         public BinaryNode(T element, BinaryNode<T> left, BinaryNode<T> right) {
15             this.element = element;
16             this.left = left;
17             this.right = right;
18         }
19
20         public String toString() {
21             return element.toString();
22         }
23     }
24
25     private BinaryNode<T> root;
26
27     public BinarySearchTree() {
28         root = null;
29     }
30
31     public void insert(T ele) {
32         root = insert(ele, root);// 每次插入操作都会‘更新‘根节点.
33     }
34
35     private BinaryNode<T> insert(T ele, BinaryNode<T> root) {
36         if (root == null)
37             return new BinaryNode<T>(ele);
38         int compareResult = ele.compareTo(root.element);
39         if (compareResult > 0)
40             root.right = insert(ele, root.right);
41         else if (compareResult < 0)
42             root.left = insert(ele, root.left);
43         else
44             ;
45         return root;
46     }
47
48     public int height() {
49         return height(root);
50     }
51
52     private int height(BinaryNode<T> root) {
53         if (root == null)
54             return -1;// 叶子节点的高度为0,空树的高度为1
55
56         return 1 + (int) Math.max(height(root.left), height(root.right));
57     }
58
59     public static void main(String[] args) {
60         BinarySearchTree<Integer> intTree = new BinarySearchTree<>();
61                 //统计每棵树有63个节点,共30棵树的平均高度
62         double averHeight = intTree.averageHeigth(30, 63, intTree);
63         System.out.println("averageheight = " + averHeight);
64     }
65
66     public double averageHeigth(int tree_numbers, int node_numbers, BinarySearchTree<Integer> tree) {
67         int tree_height, totalHeight = 0;
68         for(int i = 1; i <= tree_numbers; i++){
69             int[] randomNumbers = C2_2_8.algorithm3(node_numbers);//每棵树随机生成一组序列,该序列作为节点的值
70             //build tree
71             for(int j = 0; j < node_numbers; j++)//将一组节点插入到树中
72             {
73                 tree.insert(randomNumbers[j]);
74                 System.out.print(randomNumbers[j] + " ");
75             }
76             System.out.println();
77             tree_height = tree.height();
78             System.out.println("height:" + tree_height);
79
80             totalHeight += tree_height;//统计树高之和
81             tree.root = null;//for building next tree, 参考insert()实现
82         }
83     return (double)totalHeight / tree_numbers;
84     }
85 }
86     
时间: 2024-08-25 19:50:55

二叉排序树的高度分析的相关文章

待字闺中之树的高度分析

有一个棵树,不一定是二叉树,有n个节点,编号为0到n-1.有一个数组A,数组的索引为0到n-1,数组的值A[i]表示节点i的父节点的id,根节点的父节点id为-1.给定数组A,求得树的高度. 分析这个题目我们首先把数组写出来,然后进一步分析,就很明了了,如下例子: 333-1201234根据题意: 节点0,1,2的父节点为3 节点3是根节点 节点4的父节点为2 一个很直接的解法是,遍历数组A中的每一个元素,回溯到根节点,得到这个节点的高度.遍历完毕数组之后,取最大的,就是树的高度.上面的例子大概

二叉排序树(Binary Sort Tree)

1.定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ①  若它的左子树非空,则左子树上所有结点的值均小于根结点的值: ②  若它的右子树非空,则右子树上所有结点的值均大于根结点的值: ③  左.右子树本身又各是一棵二叉排序树. 上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树. 注意: 当用线性表作为表的组织形式时,可以有三种查找法

初步学习二叉排序树

1.  二叉排序树的性质如下: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有键值相等的节点. 2.二叉树的实现 (1) 节点的定义: typedef int KeyType; typedef struct Node { KeyType m_data; //数据成员 Node *m_pLChild;//左子树: Node *m_pRChild;//右子树:

B树详解

B树 具体讲解之前,有一点,再次强调下:B-树,即为B树.因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解.如人们可能会以为B-树是一种树,而B树又是一种一种树.而事实上是,B-tree就是指的B树.特此说明. 我们知道,B 树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树.与本blog之前介绍的红黑树很相似,但在降低磁盘I/0操作方面要更好一些.许多数据

“跳跃表”简析

复杂度 空间复杂度: O(n) (期望) 跳跃表高度: O(logn)(期望) 查找:O(logn)(期望) 插入: O(logn)(期望) 删除:O(logn)(期望) 之所以在每一项后面都加一个“期望”,是因为跳跃表的复杂度分析是基于概率论的.有可能会产生最坏情况,不过这种概率极其微小. 顶层链表元素的确定方式 底层链表就是最初的链表,包含所有元素. we just like every node to be accessed sort of as quickly as possible,

数据结构的一些复习点

数据结构知识点总结 概论 1:数据的结构直接影响算法的选择和效率. 2:数据->数据元素(元素,结点,记录)数据的基本单位->数据项(字段,域)数据不可分割的最小单位 3:数据类型:原子数据类型:值不可分(整型,字符型,实型)和结构数据类型:值可分解(数组类型,结构类型)用户自己定义的 4:数据结构:逻辑结构,物理结构:存储结构(数据结构在计算机中的表示),运算特征. 逻辑结构:集合,线性结构(一对一),树型结构(一对多),图状结构(多对多) 运算:插入,删除,查找,排序. 数据结构定义:按某

二叉树增删改查 &amp;&amp; 程序实现

二叉排序树定义 一棵空树,或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值:(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值:(3)左.右子树也分别为二叉排序树:(4)没有键值相等的结点. 二叉树删除节点 二叉排序树删除节点的时候为其删除后还是一个二叉排序树,要对不同的情况进行分别处理 1.p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树.由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点. 2.p结点只有左子树PL或右子

一个java高级工程师的进阶之路

宏观方面 一. JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级) 工程师,您要对JAVA做比较深入的研究.您应该多研究一下JDBC.IO包.Util包.Text包.JMS.EJB.RMI.线程.如果可能,希望您 对JAVA的所有包都浏览一下,知道大概的API,这样您就发现其实您想实现的很多功能,通过JAVA的API都可以实现了,就不必自己费太多的脑经 了. 二. 设计模式.其实写代码是很容易的事情,我

软件测试修炼之道(转载)

软件测试修炼之道 前言 软件测试发展到今天,已经逐渐形成一门学科,但是还不够系统. 初学者面对铺天盖地的资料应该如何选取?应该从哪里入手?如何迅速的掌握各种业务各项测试技能以便开展工作?在保证测试质量的前提下,一日内编写或执行1000个测试用例是不是梦想? 入行多年者面对复杂的业务逻辑,海量的测试需求,如何在最短的时间内进行测试?如何尽可能更早的开展测试?如何对系统架构进行测试?如何全面提高测试质量与测试效率?如何百尺竿头更进一步? 本文将针对这些问题进行初步解答,主要阐述解决这些问题应该具备哪