网站首页 > 技术文章 正文
一、树
一些基本概念有:
- 节点、父节点、子节点、兄弟节点、根节点、叶子节点;
- 高度(从叶子节点往上)、深度(从根节点往下0 ^ (n-1) )、层(从根节点往下1~n);n为层数;
二、二叉树
一些基本的概念:
- 左子节点、右子节点;二叉树要求每个节点最多只能有两个子节点,但并不要求必须有两个子节点,单独有左子节点或者右子节点都是可以的;
- 满二叉树,是指所有叶子节点都在最底层,除了叶子节点以外,每个节点都有左右两个子节点;
- 完全二叉树,是指所有叶子节点都在最底下两层,最后一层的叶子节点是从左到右依次排列的,中间不能有空缺,其它层节点个数都要达到最大,不能有空缺;
- 存储方法有链式存储法、顺序存储法;
- 大部分二叉树都可以使用如下链式存储法来进行表示,必然要左右节点空间来指向各自的左子节点和右子节点;
- 顺序存储法则是利用一个数组,将当前节点存放在下标为i的地址中,那么左子节点就存放在2i的地址中,右子节点存放在2i+1的地址中;反过来,已知某个节点位置为k,那么它的父节点位置就是k/2;但是当二叉树不是一颗完全二叉树的时候,就会比较浪费数组存储空间;因此,当二叉树为完全二叉树的时候,采用顺序存储是最优的;
- 遍历分为前序遍历、中序遍历和后序遍历;
- 前序遍历,先自己,再左边,最后右边;
- 中序遍历,先左边,再自己,最后右边;
- 后续遍历,先左边,再右边,最后自己;
三、二叉查找树
在二叉树的基础上,满足如下条件:对于任意一个节点,其左子树上的每个节点值都要小于当前节点的值,其右子树上的每个节点值都要大于当前节点的值;
- 查找,目标元素target和当前节点比较,如果比当前节点小那么就在左子树中继续查找,反之则在右子树中查找;
- 插入,目标元素target和当前节点比较,如果比当前节点小并且当前节点没有左子树,那么作为左子节点插入,如果有左子树,那么继续往左遍历;如果比当前节点大并且当前节点没有右子树,那么作为右子节点插入,如果有右子树,那么继续往右遍历;
- 删除,先找到目标元素,如果目标没有子节点,直接将其删除即可;如果目标有子节点(左右子节点都可),那么将目标节点的父节点指向目标节点的子节点即可;如果目标节点同时拥有左右子树,那么就需要在右子树中找到最小值替换当前节点;(如果想要提高删除的性能,我们还是可以采用标记删除法,以空间换时间)
- 查找最大值和最小值;
- 寻找给定元素的前驱和后继节点;
- 中序遍历输出完全有序的数列,时间复杂度O(n),相较于原先讲过的八大排序算法来说,算是最好的排序算法了;
- 重复数据的存储;
- 相同值存放在同一个节点;
- 相同值存放在右子树;但是要求在查找和删除的时候,一定要遍历到叶子节点才能找到所有相同的元素;
- 时间复杂度分析,在最坏的情况下,二叉查找树退化为链表,那么所有操作的时间复杂度都是O(n),但是在完全二叉树时,时间复杂度取决于树的高度,就是O(logn);
四、平衡二叉查找树
如何让二叉查找树尽量保持平衡,让时间复杂度维持在O(logn),这是平衡二叉查找树需要做的事情。那什么样子的二叉查找树可以被称为平衡的二叉查找树呢?
严格的定义就是:任意一个节点的左右子树的高度相差不能大于1;比如AVL树,这就是一种高度平衡的,完全符合平衡二叉树定义的。
但是,比较严格的平衡二叉树实现起来有些复杂,需要耗费过多的资源在平衡高度差不超过1这个条件上面,反而矫枉过正了。因此,我们只要能设计出一种二叉查找树,使得所有节点的左右子树看起来相对均衡,那么也可以将它称为符合要求的平衡二叉查找树,比如下面的红黑树。
五、红黑树
红黑树是一种不严格的平衡二叉查找树,它具有以下要求:
- 根节点是黑色的;
- 每个叶子节点都是黑色的空节点,不存储数据;
- 任何上下相邻的节点都不能同时为红色,红色节点是被黑色节点隔开的;
- 每个节点到到其所有叶子节点的路径都包含相同数目的黑色节点;
- 插入的节点必须是红色的,新插入的节点都是放在叶子节点上的;
红黑树在插入节点时,如果父节点是黑色的,那么直接插入就行;如果插入的节点是根节点,那么将它改为黑色即可;除此之外的任何情况,都会破坏如上红黑树的要求,此时就需要通过左旋、右旋或者改变颜色才能重新符合红黑树的要求。红黑树的实现过程和平衡过程都比较复杂,一般了解即可。
红黑树具有稳定的性能,在插入、删除和查找时都能稳定在O(logn),同时不会浪费太多资源进行平衡的操作,所以在工业运用上,比严格的平衡二叉查找树要更加地受欢迎。
六、递归树
递归树主要可以用来分析复杂算法的时间复杂度;比如原先说过的归并排序,时间复杂度是O(logn),这个使用递归树怎么分析呢?
归并排序的过程就是每次分解都是1/2,直至每个节点只有一个元素为止,然后从下往上进行相邻节点的归并排序,直至归并为一个数列。
分解的过程时间耗费比较小,因为可以利用数组随机访问的特性一分为二,所以时间可以记为常数C;
归并的时候每层都需要比较n个元素,所以时间复杂度为O(n),假设树的高度为h,那么时间复杂度就是O(hn),其中高度怎么计算呢?在满二叉树的时候,树的高度可以表示为logn,所以归并过程的时间复杂度就近似为O(nlogn),那么整个分解和归并的时间复杂度就是O(C+nlogn),去掉低阶,最终得到归并排序的时间复杂度就是O(logn)。
七、总结
二叉树比散列表的优势在哪里?
- 散列表中的数据是无序存储的,如果我们需要有序的数列,就必须先排序,时间复杂度取决于你用的排序算法以及无序数据的排列情况,但是肯定不会好于O(n),但是二叉查找树,又称二叉排序树天然就是有序的,只要按照中序遍历输出即可,时间复杂度稳定为O(n);
- 散列表有扩容操作,哈希计算操作,还会有冲突再散列的问题,其时间效率并不稳定;而平衡二叉树能让查找、插入和删除的时间复杂度能稳定在O(logn);当数据量大的时候,平衡二叉树的优势和性能将会远超散列表;
- 散列表实现起来比较复杂,需要考虑散列函数的设计、装载因子的设计、扩容和缩容方案、冲突再散列如何解决等;而平衡二叉树只需要考虑平衡的问题,比较简单,方案也比较成熟;
猜你喜欢
- 2024-10-25 《王牌部队》高粱拿了“喜剧人”剧本,笑点泪点都被他承包了
- 2024-10-25 纯爱小说推荐|生活所迫,我只能把你的后宫变成我的兄弟了
- 2024-10-25 占星秒懂|宫位的形成与解析(下) 宫位意思
- 2024-10-25 农村兄弟建双拼更有气势还省钱,2020年超受欢迎的双拼户型分享
- 2024-10-25 我爸说,“你没有结婚,我在村子里比做贼还丢人!”
- 2024-10-25 「漫步计算机系统」之数据结构与算法(18):红黑树结点的删除
- 2024-10-25 IT兄弟连 HTML5教程 CSS3揭秘 CSS3概述
- 2024-10-25 通过css类/选择器选取元素 文档结构和遍历 元素树的文档
- 2024-10-25 琅琊榜:兄弟之情,远比男女之情更加动人
- 2024-10-25 参加兄弟婚礼祝福语 参加兄弟婚礼祝福语简短
你 发表评论:
欢迎- 最近发表
-
- 吴谨言专访大反转!痛批耍大牌后竟翻红,六公主七连发力显真诚
- 港股2月28日物业股涨幅榜:CHINAOVSPPT涨1.72%位居首位
- 港股2月28日物业股午盘:CHINAOVSPPT涨1.72%位居首位
- 港股3月2日物业股涨幅榜:CHINAOVSPPT涨1.03%位居首位
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%
- 天赋与心痛的背后:邓鸣贺成长悲剧引发的深刻反思
- 冯小刚女儿徐朵追星范丞丞 同框合照曝光惹人羡,回应网友尽显亲民
- “资本大佬”王冉:51岁娶小17岁童瑶,并承诺余生为娇妻保驾护航
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%位居首位
- 「IT之家开箱」vivo S15 图赏:双镜云窗,盛夏风光
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)