数据结构系列文章—树(1)

     我以前学习过数据结构的知识,因为长时间没有用到,所以遗忘了。现在用到数据结构的知识,感觉很多都不记得了,为了加深自己对数据结构知识的印象,也为了防止忘记这部分知识,我决定把这部分知识记录下来,以备查阅。真应了孔子的那句话“学而时习。学而不思则罔,思而不学则殆”,与诸君共勉。

      数据结构,分2块,是数据的逻辑结构和数据的存储结构。树的逻辑结构主要分2类,线性结构和非线性结构。线性结构,比如像队列、栈、数组,这类都是线性结构。非线性结构,比如像矩阵、树、图,这类都是非线性结构。树的存储结构,有顺序存储、链表存储等。      

树的相关概念

树(Tree)是n(n ≥ 0)个结点得有限集。n = 0时称为空树。在任何一颗非空树中:

(1)有且仅有一个特定的称为根(Root)的结点;

(2)当n > 1时,其余结点可分为m(m > 0)个互不相交的有限集,其中每个集合本事又是一棵树,并且称为根的子树。

上图,就是1棵树,整棵树的根节点就是A。B、C、D、E、F均为A的子树。

度的概念:与图论中的“度”不同,树的度是如下定义的:有根树T中,结点x的子女数目称为x的度。也就是:在树中,结点有几个分叉,度就是几。

如上图,D结点有3个子结点G、H、J,所以D的度就是3。

树的深度:结点的层次从根开始定义起,根为第一层,根的子节点为第二层。树中结点的最大层次称为树的深度或高度。下图树的深度为4。

二叉树的定义:二叉树的每个结点至多只有二棵子树(不存在度大于2的情况),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有(2的i-1次方)个结点;深度为k的二叉树至多有(2^k) - 1个结点;对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

满二叉树

满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点。也可以这样理解,除叶子结点外的所有结点均有两个子结点。节点数达到最大值,所有叶子结点必须在同一层上。

满二叉树的性质:

  1) 一颗树深度为h,最大层数为k,深度与最大层数相同,k=h;

  2) 叶子数为2h;

  3) 第k层的结点数是:(2的i-1次方);

  4) 总结点数是:(2^k) - 1,且总节点数一定是奇数。

完全二叉树

完全二叉树:若设二叉树的深度为h,除第 h 层外,从 1 到 h-1 层必须达到最大节点数,第 h 层可以不是满的,但是第 h 层的所有节点必须集中在最左边。 这就是完全二叉树。

完全二叉树,有右子树必有左子树。

当我们用数组实现一个完全二叉树时,叶子节点可以按从上到下、从左到右的顺序依次添加到数组中,然后知道一个节点的位置,就可以轻松地算出它的父节点孩子节点的位置。

以上面图中完全二叉树为例,标号为 2 的节点,它在数组中的位置也是 2,它的父节点就是 (k/2 = 1),它的孩子节点分别是 (2k=4) 和 (2k+1=5),别的节点也是类似。

完全二叉树的应用场景:完全二叉树的特点是:“叶子节点的位置比较规律”。因此在对数据进行排序或者查找时可以用到它,比如堆排序就使用了完全二叉树。

完全二叉树是效率很高的数据结构,堆是一种完全二叉树或者近似完全二叉树,所以效率极高,像十分常用的排序算法、Dijkstra算法、Prim算法等都要用堆才能优化,二叉排序树的效率也要借助平衡性来提高,而平衡性基于完全二叉树。

二叉查找树(又称二叉排序树)

我们知道,二分查找可以缩短查找的时间,但是它要求 查找的数据必须是有序的。每次查找、操作时都要维护一个有序的数据集,于是有了二叉查找树这个概念。

二叉查找树(又称二叉排序树),它是具有下列性质的二叉树:

  1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

  2. 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;

  3. 左、右子树也分别为二叉排序树。

二叉查找树的特点:对二叉查找树进行中序遍历,即可得到有序的数列。

比如上图,中序遍历结果是:1 3 4 6 7 8 10 13 14

二叉查找树的性能:

在最好的情况下,二叉排序树的查找效率比较高,是 O(logn),其访问性能近似于折半查找;

但最差时候会是 O(n),比如插入的元素是有序的,生成的二叉排序树就是一个链表,这种情况下,需要遍历全部元素才行(见下图 b)。

如果我们可以保证二叉排序树不出现上面提到的极端情况(插入的元素是有序的,导致变成一个链表),就可以保证很高的效率了。

但这在插入有序的元素时不太好控制,按二叉排序树的定义,我们无法判断当前的树是否需要调整。

因此就要用到平衡二叉树(AVL 树)了。

平衡二叉树(AVL树)

平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用算法有红黑树、AVL树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log2n),大大降低了操作的时间复杂度。

以 12 为根节点,当添加 24 为它的右子树后,根节点的左右子树高度差为 1,这时还算平衡,这时再添加一个元素 28:

这时根节点 12 觉得不平衡了,我左孩子一个都没有,右边都有俩了,超过了之前说的最大为 1,不行,给我调整!

于是我们就需要调整当前的树结构,让它进行旋转。

因为最后一个节点加到了右子树的右子树,就要想办法给右子树的左子树加点料,因此需要逆时针旋转,将 24 变成根节点,12 右旋成 24 的左子树,就变成了这样(有点丑哈哈):

这时又恢复了平衡,再添加 37 到 28 的右子树,还算平衡:

这时如果再添加一个 30,它就需要在 37 的左子树:

这时我们可以看到这个树又不平衡了,以 24 为根节点的树,明显右边太重,左边太稀,想要保持平衡就 24 得让位给 28,然后变成这样:

丑了点,但的确保持了平衡。

依次类推,平衡二叉树在添加和删除时需要进行旋转保持整个树的平衡,内部做了这么复杂的工作后,我们在使用它时,插入、查找的时间复杂度都是 O(logn),性能已经相当好了。

参考资料

数据结构中各种树 - xin Tech - 博客园

完全二叉树 - wulongming88 - 博客园

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值