1- # 1 有序表原理及扩展
2-
3- ## 1.1 搜索二叉树
1+ - [ 1 有序表原理及扩展] ( #1 )
2+ * [ 1.1 搜索二叉树] ( #11 )
3+ * [ 1.2 搜索二叉树的增删改查] ( #12 )
4+ + [ 1.2.1 搜索二叉树的查找和添加] ( #121 )
5+ * [ 1.3 传统搜索二叉树存在的问题] ( #13 )
6+ + [ 1.3.1 平衡搜索二叉树] ( #131 )
7+ + [ 1.3.2 左旋和右旋] ( #132 )
8+ * [ 1.4 有序表] ( #14 )
9+ * [ 1.5 有序表的实现(AVL树,SB树,红黑树)] ( #15 )
10+ + [ 1.5.1 AVL树] ( #151 )
11+ - [ 1.5.1.1 AVL树针对某个节点的平衡性处理] ( #1511 )
12+ + [ 1.5.2 SB树] ( #152 )
13+ - [ 1.5.2.1 SB树针对某个节点的平衡性处理] ( #1521 )
14+ + [ 1.5.3 红黑树] ( #153 )
15+ - [ 1.5.3.1 红黑树针对某个节点的平衡性处理] ( #1531 )
16+ * [ 1.5.3.1.1 Redis为什么选择跳表的结构?] ( #15311 )
17+ * [ 1.6 跳表SkipList(也可实现有序表功能)] ( #16 )
18+ * [ 1.7 有序表例题实战] ( #17 )
19+ + [ 1.7.1 哪些情况下需要改写系统的有序表?] ( #171 )
20+
21+ <h1 id =' 1 ' >1 有序表原理及扩展</h1 >
22+
23+ <h2 id =' 11 ' >1.1 搜索二叉树</h2 >
424
525经典的搜索二叉树,是没有重复值的,任何节点为头的数,左孩子都比自己小,右孩子都比自己大
626
15353、如果有重复节点的需求,可以在一个节点内部增加数据项
1636
1737
38+ <h2 id =' 12 ' >1.2 搜索二叉树的增删改查</h2 >
1839
19- ## 1.2 搜索二叉树的增删改查
20-
21-
22- ### 1.2.1 搜索二叉树的查找和添加
40+ <h2 id =' 121 ' >1.2.1 搜索二叉树的查找和添加</h2 >
2341
2442- 查找
2543
@@ -489,8 +507,7 @@ public class AbstractBinarySearchTree {
489507
490508```
491509
492-
493- ## 1.3 传统搜索二叉树存在的问题
510+ <h2 id =' 13 ' >1.3 传统搜索二叉树存在的问题</h2 >
494511
495512
4965131)基础的搜索二叉树,添加、删除时候不照顾平衡性
@@ -506,13 +523,13 @@ public class AbstractBinarySearchTree {
506523平衡二叉树的定义,任何子树,左子树的高度和右子树的高度差,不大于1。所以对于n个节点,平衡二叉树的高度,就是logN
507524
508525
509- ### 1.3.1 平衡搜索二叉树
526+ < h3 id = ' 131 ' > 1.3.1 平衡搜索二叉树</ h3 >
510527
511528
512529平衡搜索二叉树,就是在插入和删除的过程中,动态的保持平衡性。保持平衡的代价保持在logN。平衡搜索二叉树的实现由很多,红黑树只是其中一种
513530
514531
515- ### 1.3.2 左旋和右旋
532+ < h3 id = ' 132 ' > 1.3.2 左旋和右旋</ h3 >
516533
517534左旋和右旋针对头结点而言的,即对哪个头结点进行左旋还是右旋;顾名思义如果对头结点为a的子树右旋,那么a倒到右边,a的左孩子顶上来,到a原来的位置上去。a原来左孩子的右孩子,现在当做a的左孩子,如下图
518535
@@ -641,8 +658,7 @@ extends AbstractBinarySearchTree {
641658```
642659
643660
644-
645- ## 1.4 有序表
661+ <h2 id =' 14 ' >1.4 有序表</h2 >
646662
647663
648664在Java中,就是TreeMap,有序表和Hash表(HashMap)的操作类似,但是有序表中自动把我们的key排好了顺序,我们也可以传入比较器,自定义对比和排序的规则;我们可以通过TreeMap直接得到最大节点和最小节点,也可以获取大于某个值的第一个Key是什么等等
@@ -658,7 +674,7 @@ extends AbstractBinarySearchTree {
6586742、使用有序表的Key必须是可以比较的,没法自然比较的需要传入自定义比较器
659675
660676
661- ## 1.5 有序表的实现(AVL树,SB树,红黑树)
677+ < h2 id = ' 15 ' > 1.5 有序表的实现(AVL树,SB树,红黑树)</ h2 >
662678
663679在有序表中,有序表是一种规范,类似于接口名。规范为key要按序组织,所有操作要是O(logN)等。各种树结构可以实现有序表的功能。其中红黑树只是有序表的一个实现
664680
@@ -688,8 +704,8 @@ AVL树最严格、SB树稍宽松、红黑树最宽松
688704
689705
690706
707+ <h3 id =' 151 ' >1.5.1 AVL树</h3 >
691708
692- ### 1.5.1 AVL树
693709
694710是这三个平衡搜索二叉树中,平衡性最严格的,左树高度和右树高度的绝对值,严格小于2
695711
@@ -698,7 +714,8 @@ AVL树在插入节点的时候,只会向上检查节点的平衡性有没有
698714==实质上三种树删除和插入节点,检查哪些节点需要调整平衡都是这样的查找规则,对于删除来说,只有左树和只有右树没影响,如果左右树都存在,是去检查后继节点原来所在的位置向上的平衡性。只是具体到某个节点平衡性的处理上,三种树不一样==
699715
700716
701- #### 1.5.1.1 AVL树针对某个节点的平衡性处理
717+ <h4 id =' 1511 ' >1.5.1.1 AVL树针对某个节点的平衡性处理</h4 >
718+
702719
7037201、该节点左树高度和右树高度差的绝对值|L-R|,小于2。不违规,无须调整
704721
@@ -1003,7 +1020,7 @@ public class AVLTree extends AbstractSelfBalancingBinarySearchTree {
10031020```
10041021
10051022
1006- ### 1.5.2 SB树
1023+ < h3 id = ' 152 ' > 1.5.2 SB树</ h3 >
10071024
10081025
10091026对于平衡性而言,任何叔叔节点的子节点格式,不少于该节点的任何一个侄子节点子节点的个数
@@ -1025,7 +1042,8 @@ e-->g
10251042
10261043对于这种约束,也可保证任何节点的左右节点的个数不会有很大悬殊,即使高度不满足严格相减的绝对值小于2,也无伤大雅。整体仍然是O(logN)
10271044
1028- #### 1.5.2.1 SB树针对某个节点的平衡性处理
1045+ <h4 id =' 1521 ' >1.5.2.1 SB树针对某个节点的平衡性处理</h4 >
1046+
10291047
103010482007年,读高中的时候,承志峰研究出来的;常被用作比赛时,AVL树反而在ACM比赛中使用的相对少点
10311049
@@ -1705,7 +1723,7 @@ public class Code02_SizeBalancedTreeMap {
17051723```
17061724
17071725
1708- ### 1.5.3 红黑树
1726+ < h3 id = ' 153 ' > 1.5.3 红黑树</ h3 >
17091727
171017281、 节点有红有黑
17111729
@@ -1719,8 +1737,7 @@ public class Code02_SizeBalancedTreeMap {
17191737从第三点和第四点可以推出,任何长链(黑红交替)和任何段链(都为黑)保证黑一样多,那么长链的长度一定不会比短链长度的二倍还要大。实质上上面条件的目的也是保证最长的链不要比最短的链2倍还多,一定程度上保证了平衡性
17201738
17211739
1722-
1723- #### 1.5.3.1 红黑树针对某个节点的平衡性处理
1740+ <h4 id =' 1531 ' >1.5.3.1 红黑树针对某个节点的平衡性处理</h4 >
17241741
17251742红黑树本质上也是搜索二叉树,搜索二叉树怎么增加和删除节点,红黑树相同;同样的加完节点,删除完节点,之后从受影响的节点往上都进行平衡性检查,几种有序表的实现只有检查平衡性的评估指标不同
17261743
@@ -1744,8 +1761,7 @@ public class Code02_SizeBalancedTreeMap {
17441761
17451762红黑树,在(AVL,SB) 和 硬盘的树(B,B+)树之间达到平衡。各有取舍
17461763
1747-
1748- ##### Redis为什么选择跳表的结构?
1764+ <h5 id =' 15311 ' >1.5.3.1.1 Redis为什么选择跳表的结构?</h5 >
17491765
17501766Redis为什么选择跳表的结构,而不是AVL和SB树呢,实质上可以选择,但是考虑到redis可能需要对有序表进行序列化的要求,SkipList就是多层的线性结构,比较好序列化。AVL和SB是个结构化的东西,不好序列化;一种技术的选型,需要根据自己的生存状态去选择的
17511767
@@ -1755,7 +1771,7 @@ Redis为什么选择跳表的结构,而不是AVL和SB树呢,实质上可以选
17551771
17561772
17571773
1758- ## 1.6 跳表SkipList(也可实现有序表功能)
1774+ < h2 id = ' 16 ' > 1.6 跳表SkipList(也可实现有序表功能)</ h2 >
17591775
17601776
17611777==最烧脑的结构==
@@ -2050,8 +2066,7 @@ public class Code03_SkipListMap {
20502066```
20512067
20522068
2053-
2054- ## 1.7 有序表例题实战
2069+ <h2 id =' 17 ' >1.7 有序表例题实战</h2 >
20552070
20562071- 例题1
20572072
@@ -2072,7 +2087,7 @@ public class Code03_SkipListMap {
20722087整个流程,只需要运用有序表的基本功能,原始的有序表已经能够满足需求,无需改写有序表,用系统实现的即可;
20732088
20742089
2075- ### 1.7.1 哪些情况下需要改写系统的有序表?
2090+ < h3 id = ' 171 ' > 1.7.1 哪些情况下需要改写系统的有序表?</ h3 >
20762091
20772092- 例题-leetcode原题
20782093
0 commit comments