前言
数据结构:数据在计算机上的存储、组织形式
线性表:包含多个数据元素的有限序列,元素之间一般首尾相接(特殊的比如循环链表),是一对一的线性关系,它包括顺序表和链表,常见的数据结构有:数组、栈、队列、链表等
一、树
由n个节点组成的、具有层次结构和树状结构性质的数据的集合,是一种非线性结构,是一对多的关系,可以通过家族中的族谱来辅助理解,一个节点可以有n个子节点但是子节点(根节点除外)却有且仅有一个父节点
节点的度:节点的分支个数/子节点个数(节点的直接孩子的个数,不包括孙子…),如图节点1的度是3
树的度:树中所有节点的度的最大值
根节点:位于树的最顶层,所有节点都是由它发散而来,整个树中唯一没有父节点的节点,如图这颗树的根节点是节点1
叶子节点:没有子节点的节点即度为0的节点,如图3 5 6 7 8
节点的高度:自下而上节点的最大层数,如节点1的度是3,又因为节点1是根节点,所以整颗树的高度也是3
树的高度:所有节点高度的最大值,也可以理解为根节点的度
节点的深度:自上而下,如节点2的深度为2
树的深度:所有节点深度的最大值
森林:由多个互不相交的树组成,树去掉根节点便成了森林,为森林加上根节点便成了树
二、二叉树
所有节点的度都不超过2的树称为二叉树、二叉树的遍历就是遍历二叉树中所有节点的数据,常用的有三种方式:前序遍历、中序遍历、后序遍历,这里前中后是相对中间节点而言的
前序遍历:中=>左=>右,A B D E G C F
中序遍历:左=>中=>右,D B G E A C F
后序遍历:左=>右=>中,D G E B F C A
满二叉树:叶子节点都在最后一层,除叶子节点外每个节点都有2个子节点,即各层都是满的,若树的高度是
n
n
n则满二叉树的总节点数量为
2
n
−
1
2^{n}-1
2n−1 ,深度为
i
i
i的层的节点数为
2
i
−
1
2^{i-1}
2i−1
完全二叉树:除最后一层外其它层必须都是满的,如果最后一层不满则空出的部分必须是右侧连续的部分,即最后一层节点靠左排列,所以满二叉树必是完全二叉树
三、二叉查找树
由于二叉树中的数据是无序的,所以要查找某个数据,最坏的情况则要遍历所有节点,平均时间复杂度是
O
(
n
)
O(n)
O(n),非常不利于查找,于是为了方便查找和插入我们对二叉树中的数据进行排序,让二叉树中所有的左子树上的节点的值都小于根节点,右子树上的节点的值都大于根节点,于是就有了二叉查找树,又称二叉排序树、二叉搜索树
可以发现对如图二叉查找树进行中序遍历会得到1 2 3 4 6 7,这样的设计使得我们可以通过与当前节点的对比定位到数据是在左子树还是右子树,加快了查找效率。这种方法运用了二分查找的思想,最好时间复杂度
O
(
l
o
g
n
)
O(logn)
O(logn),最坏的查找次数等于树的高度,当二叉查找树退化为单链表时最坏时间复杂度可达
O
(
n
)
O(n)
O(n),所以二叉查找树应该越“宽”越好,深度越小越好。为了使树中每个节点的深度尽量小以提高查询效率,所有又有了平衡二叉查找树(AVL树)与红黑树
四、平衡二叉查找树(AVL树)
在二叉查找树中任意节点的两颗子树的高度相差不超过1,这样的二叉查找树称为平衡二叉查找树,左右子树的高度差称为平衡因子
一旦由于插入或者删除操作引起了平衡二叉查找树的不平衡,就需要进行旋转再平衡,这样做是为了保证平衡二叉查找树在查找、插入和删除时的平均和最坏时间复杂度是
O
(
l
o
g
n
)
O(logn)
O(logn)
五、红黑树
红黑树是一种自平衡的二叉查找树,除具备二叉查找树的基本特性之外还具有以下性质:
- 节点是红色或者黑色
- 根节点是黑色
- 叶子节点是黑色的空节点
- 红色节点必有2个黑色的子节点(保证了从任意节点到根节点的路径上不可能出现2个连续的红色节点)
- 任意节点到其每个叶子节点的所有路径上的黑色节点数目是相同的
由以上性质可以得出从根节点到叶子节点的最长路径不超过最短路径的2倍,节点的路径长度(高度)决定着对节点的查找、插入与删除效率,所以正是由于这些特性使得红黑树的查找、插入与删除的最坏时间复杂度不超过
O
(
l
o
g
n
)
O(logn)
O(logn)
当插入或者删除操作使得红黑树失去平衡,可以通过变色与左右旋转来达到再平衡
应用:Java8中的HashMap就用到了红黑树
六、AVL树与红黑树的对比
- 就查找操作而言,AVL树的效率更高,因为平衡因子不大于1的限制使得AVL树更加平衡,减小了树的高度,从而减小了树的平均搜索长度
- 就插入和删除而言,一般认为红黑树的效率更高,因为不严格要求平衡因子绝对不大于1,所以减小了再平衡需要的旋转操作次数,可以认为是牺牲平衡换取插入和删除时间
- 因为红黑树的特点使得红黑树的再平衡可以在3次旋转之内解决,而AVL树的再平衡并没有旋转次数上限