From 1bdd96a345efd5a800c74fcb252fee342621ff83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=89=E6=96=87=E6=9D=B0?= <510495266@qq.com> Date: Sat, 16 Oct 2021 01:03:56 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E7=BA=BF=E6=80=A7=E6=8E=A2=E6=B5=8B?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3 Hash Table/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/3 Hash Table/README.md b/3 Hash Table/README.md index aecec75..409a780 100644 --- a/3 Hash Table/README.md +++ b/3 Hash Table/README.md @@ -97,7 +97,9 @@ hash 表有一个特性, 随着元素越来越多, 新插入一个元素发 ### 线性探测法 -使用大小为M的数组保存N个键值对,当碰撞发生时,直接检查散列表中的下一个位置。 +使用大小为M的数组保存N个键值对,当碰撞发生时,直接检查散列表中的下一个位置,如果发现空位置插入新元素。 + +查找key时,先通过 hash(key) 得到 index, 看index 处 key 是否已经存在,不存在,就向后遍历数组。 ## 数据结构和算法 From 30c899160d74d25ec9c247782888c795b07f48b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=89=E6=96=87=E6=9D=B0?= <510495266@qq.com> Date: Sat, 16 Oct 2021 01:32:20 +0800 Subject: [PATCH 2/3] update rb avl bst tree --- 3 Hash Table/HashMap in Java.md | 2 +- 4 Tree/2-二叉查找树/二叉查找树.md | 16 +++++++++++----- 4 Tree/3-平衡树AVL/AVLTree.c | 3 --- 4 Tree/3-平衡树AVL/README.md | 18 ++++++++++++------ 4 Tree/9-红黑树 R-B tree/红黑树.md | 15 +++++++++++++++ 4 Tree/README.md | 2 -- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/3 Hash Table/HashMap in Java.md b/3 Hash Table/HashMap in Java.md index f9854d3..30ca859 100644 --- a/3 Hash Table/HashMap in Java.md +++ b/3 Hash Table/HashMap in Java.md @@ -2,7 +2,7 @@ java 中 hashmap的实现原理。 - +[红黑树参考这里](../4%20Tree/9-红黑树%20R-B%20树) ## 数据结构 diff --git a/4 Tree/2-二叉查找树/二叉查找树.md b/4 Tree/2-二叉查找树/二叉查找树.md index 6e23115..965a982 100644 --- a/4 Tree/2-二叉查找树/二叉查找树.md +++ b/4 Tree/2-二叉查找树/二叉查找树.md @@ -1,14 +1,16 @@ - -## 二叉查找树 +# 二叉查找树 二叉查找树(Binary search tree),也叫`有序二叉树(Ordered binary tree)`,`排序二叉树(Sorted binary tree)`。是指一个空树或者具有下列性质的二叉树: 1. 若任意节点的左子树不为空,则左子树上所有的节点值小于它的根节点值 2. 若任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值 3. 任意节点左右子树也为二叉查找树 - 4. 没有键值相等的节点 + 4. 没有键值(key)相等的节点 - ``` +有序的二叉查找树,中序遍历结果是递增的。 + + +``` typedef int ElemType; typedef struct BiSearchTree{ ElemType key; @@ -18,7 +20,7 @@ BiSearchTree *bisearch_tree_insert(BiSearchTree *tree,ElemType node); int bisearch_tree_delete(BiSearchTree **tree,ElemType node); int bisearch_tree_search(BiSearchTree *tree,ElemType node); - ``` +``` 删除节点,需要重建排序树 @@ -107,3 +109,7 @@ int bisearch_tree_delete(BiSearchTree **tree,ElemType node){ } ``` + + + + diff --git a/4 Tree/3-平衡树AVL/AVLTree.c b/4 Tree/3-平衡树AVL/AVLTree.c index dd1cc3c..fdcb6c3 100644 --- a/4 Tree/3-平衡树AVL/AVLTree.c +++ b/4 Tree/3-平衡树AVL/AVLTree.c @@ -1,7 +1,4 @@ - /* - - 记于2014-2-28 by @nonstriater */ diff --git a/4 Tree/3-平衡树AVL/README.md b/4 Tree/3-平衡树AVL/README.md index f901c47..1eaf3b9 100644 --- a/4 Tree/3-平衡树AVL/README.md +++ b/4 Tree/3-平衡树AVL/README.md @@ -1,9 +1,9 @@ -## 自平衡二叉查找树(AVL tree) +# 自平衡二叉查找树(AVL tree) 自平衡二叉查找树(AVL tree): 首先也是二次查找树,其实 任何2个子树的高度差不大于1 -在删除,插入的过程中不断调整子树的高度,保证平均和最坏情况下都是O(logn) +在删除,插入的过程中不断调整子树的高度,保证查找操作平均和最坏情况下都是O(logn) -Adelson-Velskii 和 Landis 1962年 创造。 +Adelson-Velskii 和 Landis 1962年 创造, 因此叫做 AVL 树。 1) 平衡因子 -1 0 1 节点是正常的。平衡因子 = 左子树高度-右字数高度 2) 除此之外的节点是不平衡的,需要重新平衡这个树。也就是AVL旋转 @@ -33,16 +33,22 @@ d: 先右后左旋转:(RL型:节点X的右孩子的左孩子上插入新元素 (LL型) (RR) (LR) (RL) + ## 删除节点 - - - 可以看到,为了保证高度平衡,插入和删除操作代价增加 ## AVL 实现过程中的问题 +AVL 是严格的平衡二叉树,平衡条件必须满足,即所有节点的左右子树高度差的绝对值不超过1; + +执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入与删除次数比较少,但查找多的情况。 + +由于维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部平衡而不是非常严格整体平衡的红黑树()。 + + + diff --git a/4 Tree/9-红黑树 R-B tree/红黑树.md b/4 Tree/9-红黑树 R-B tree/红黑树.md index f963509..2d1fdbf 100644 --- a/4 Tree/9-红黑树 R-B tree/红黑树.md +++ b/4 Tree/9-红黑树 R-B tree/红黑树.md @@ -10,11 +10,26 @@ * java 中 HashMap、TreeMap 的底层实现,当HashMap中元素大于8个时,HashMap底层存储实现改为红黑树,以提高元素搜索速度。 关于 HashMap 实现解析参考 [这里](../../3%20HashTable/HashMap%20in%20Java.md) * 广泛应用Linux 的进程管理、内存管理,设备驱动及虚拟内存跟踪 +* epoll的的的实现采用红黑树组织管理的的的sockfd,以支持快速的增删改查 +* Nginx的的的中用红黑树管理定时器,因为红黑树是有序的,可以很快的得到距离当前最小的定时器 +### RB tree 特点 +* 每个节点非红即黑 +* 根节点是黑的 +* 每个叶节点(叶节点即树尾端NULL指针或NULL节点)都是黑的 +* 如果一个节点是红的,那么它的两儿子都是黑的 +* 对于任意节点而言,其到叶子点树NULL指针的每条路径都包含相同数目的黑节点 +* 每条路径都包含相同的黑节点 +在每个节点增加一个存储位表示节点的颜色,可以是红或黑(非红即黑);通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍; + +因此,红黑树是一种弱平衡二叉树(由于是弱平衡,可以看到,在相同的节点情况下,AVL树的高度低于红黑树)。相对于要求严格的AVL树来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,我们就用红黑树。 + + +也就是说,红黑树牺牲掉一定的平衡性(牺牲查找性能),换来了 插入,删除操作时 更少的旋转次数带来的开销。 diff --git a/4 Tree/README.md b/4 Tree/README.md index 7837139..4eb2054 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -21,8 +21,6 @@ 快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 - - ## [AVL树](3-平衡树AVL/README.md) From ae3a9ca588438222069bb14c2e73211b5fe22589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=89=E6=96=87=E6=9D=B0?= <510495266@qq.com> Date: Sat, 16 Oct 2021 01:52:41 +0800 Subject: [PATCH 3/3] update rb tree --- 4 Tree/7-B树/B树.md | 5 ++--- 4 Tree/9-红黑树 R-B tree/红黑树.md | 16 +++++++++++++++- 4 Tree/91-反向索引/反向索引.md | 1 - 4 Tree/README.md | 8 +++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/4 Tree/7-B树/B树.md b/4 Tree/7-B树/B树.md index b47b461..c2b5121 100644 --- a/4 Tree/7-B树/B树.md +++ b/4 Tree/7-B树/B树.md @@ -1,7 +1,6 @@ +# B树 -## B树 - -平衡查找树,一种多路查找树。 +一种多路平衡查找树。 能保证数据插入和删除情况下,任然保持执行效率。 diff --git a/4 Tree/9-红黑树 R-B tree/红黑树.md b/4 Tree/9-红黑树 R-B tree/红黑树.md index 2d1fdbf..a33a927 100644 --- a/4 Tree/9-红黑树 R-B tree/红黑树.md +++ b/4 Tree/9-红黑树 R-B tree/红黑树.md @@ -7,6 +7,7 @@ ### 应用场景 +* C++ STL的map和set * java 中 HashMap、TreeMap 的底层实现,当HashMap中元素大于8个时,HashMap底层存储实现改为红黑树,以提高元素搜索速度。 关于 HashMap 实现解析参考 [这里](../../3%20HashTable/HashMap%20in%20Java.md) * 广泛应用Linux 的进程管理、内存管理,设备驱动及虚拟内存跟踪 @@ -26,12 +27,25 @@ 在每个节点增加一个存储位表示节点的颜色,可以是红或黑(非红即黑);通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍; -因此,红黑树是一种弱平衡二叉树(由于是弱平衡,可以看到,在相同的节点情况下,AVL树的高度低于红黑树)。相对于要求严格的AVL树来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,我们就用红黑树。 +因此,红黑树是一种弱平衡二叉树(由于是弱平衡,可以看到,在相同的节点情况下,AVL树的高度低于红黑树)。相对于要求严格的[AVL树](../3-平衡树AVL/README.md)来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,我们就用红黑树。 也就是说,红黑树牺牲掉一定的平衡性(牺牲查找性能),换来了 插入,删除操作时 更少的旋转次数带来的开销。 +### 红黑树 & B+ 树对比 + +* 红黑树多用在内部排序,即全放在内存中的 +* B+树多用于外存上时,B+也被成为一个磁盘友好的数据结构; 这也是为什么 mysql索引使用b+树而不使用红黑树 + + +为什么使用 红黑树 而不是 B+ 树呢?原因如下: + +* 没有范围查找, 不需要 B+ +* 不需要多路平衡树,使用二路平衡,实现简单,且红黑树能兼顾 查找,删除操作的性能 + + + diff --git a/4 Tree/91-反向索引/反向索引.md b/4 Tree/91-反向索引/反向索引.md index 031c7dd..bcb9b23 100644 --- a/4 Tree/91-反向索引/反向索引.md +++ b/4 Tree/91-反向索引/反向索引.md @@ -1,6 +1,5 @@ # 反向索引 - 正排索引如 mysql中的索引实现 ,通常使用 B+ 树实现。 反向索引如何来实现呢? ### 应用场景 diff --git a/4 Tree/README.md b/4 Tree/README.md index 4eb2054..08e1edb 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -5,13 +5,13 @@ * 二叉树 * 二叉查找树 * AVL树 +* 红黑树 +* B树 : B树, B+树(mysql索引使用B+树的数据结构) * 字典树trie(前缀树,单词查找树) * 伸展树 * 后缀树 -* B树 : B树, B+树(mysql索引使用B+树的数据结构) * 红黑树 * 二叉堆(优先队列) -* 红黑树 * Treap 树 * 赫夫曼编码 Huffman @@ -24,6 +24,9 @@ ## [AVL树](3-平衡树AVL/README.md) +## [红黑树](9-红黑树%20R-B%20tree/红黑树.md) + + ## [字典树trie](4-字典树Trie/README.md) 字典树也叫前缀树,单词查找树 @@ -43,7 +46,6 @@ ## [二叉堆](8-堆/堆.md) -## [红黑树](9-红黑树%20R-B%20tree/红黑树.md) ## 赫夫曼编码 Huffman