树、二叉树

树由边连接的节点而构成:

二叉树(二叉搜索树):如果树中每个节点最多只能有两个子节点,这种树就被称为“二叉树”:

二叉树每个节点的两个子节点称为“左子节点”和“右子节点”;

二叉树中的节点不是必须有两个子节点,可以只有一个左子节点,或者只有一个右子节点,或者干脆没有子节点(叶节点);

二叉树特征定义:一个节点的左子节点的关键字值小于这个节点,右子节点的关键字值大于或等于这个节点。

二叉树的效率:

在查找过程中,需要访问每层的一个节点,所以只要知道有多少层就可以知道这些操作需要多长时间了。

特定节点数量的满树的层数


节点数(N)                                                                                            层数(L) 


1                                                                                                                 1

3                                                                                                                 2

7                                                                                                                 3

...                                                                                                                ...

1023                                                                                                           10

...                                                                                                                ...

1048575                                                                                                     20

...                                                                                                               ...

1073741823                                                                                              30


L = log2(N + 1);

因此常见树的操作时间复杂度大致是N以2为底的对数。表示为O(log2N),和二分法排序的时间复杂度保持一致。

遍历树:根据一种特定的顺序访问树的每一个节点

遍历方法:前序、中序(常用)、后序

中序遍历(递归方法代码如下):

1、调用自身来遍历节点的左子树

2、访问该节点

3、调用自身来遍历节点的右子树

private void inOrder(Node localRoot) {
    if (localRoot != null) {
        inOrder(localRoot.leftChild);
        System.out.print(localRoot.data + "   ");
        inOrder(localRoot.rightChild);
    }
}

刚开始用根(root)作为参数调用这个方法:

inOrder(root);

前序遍历(代码略):

1、访问该节点

2、调用自身遍历该节点的左子树

3、调用自身遍历该节点的右子树

后序遍历(代码略):

1、调用自身遍历该节点的左子树

2、调用自身遍历该节点的右子树

3、访问该节点

上图中的节点遍历:

中序:DBEAFCG

前序:ABDECFG

后序:DEBFGCA

至于二叉树的插入、查找、删除,不再说明;二叉树的删除比较复杂,删除不是必要的,可以在程序中避免出现(在node节点类中增加一个Boolean的属性,eg:isDeleted),删除这样的节点不会改变树的结构,但是树中依然保留着“已删除”的节点。

非平衡树:它们大部分的节点在根的一边或者另一边;有的子树也可能是非平衡的

原因:树变得不平衡是由于数据项插入顺序导致的。

如果数据项是随机插入的,树或多或少会更平衡一点;但是如果插入序列是升序(eg:5、8、11、17、19、22、31、55、86...)或者是降序(略),则所有的节点都会是右子节点(升序)或者都是左子节点(降序),这样树就会极度不平衡了(如下图)。

无论如何,在插入数据项的时候,还是会有短的升序或者降序数列出现,这会导致树的局部不平衡。

二叉树的不平衡,是它最明显的缺点;也正是二叉树的应用不广泛的原因;但它却是学习其他树(红黑树、VAL树、2-3树、B树、B+树...)的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值