《算法》三查找上

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43928720/article/details/102768569

1. 无序链表

无序链表中的顺序查找
在含有N对键值基于无序链表的符号表中,未命中的查找和插入操作都需要N次比较。命中的查找在最坏情况下需要N次比较,向一个空表中插入N个不同的键需要N^2/2次。
在表中查找一个不存在的键时,我们会将表中的每个键和给定的键比较。因为不允许出现重复的键,每次插入操作之前我们都需要这样查找一遍。

2. 有序数组

有序数组的二分查找
在N个键的有序数组中进行二分查找最多需要lgN+1次比较(无论成功与否)。
在这里插入图片描述
核心问题是我们能否找到能够同时保证查找和插入操作都是对数级别的算法和数据结构。
要支持高效的插入操作,我们似乎需要一种链式结构,但单链表是无法使用二分查找法的,因为二分查找的高效来自于能够快速通过索引取得任何子数组的中间元素,但得到一条链表的中间元素的唯一方法只能是沿链表遍历。
为了将二分查找的效率和链表的灵活性结合起来,我们需要更加复杂的数据结构。能够同时拥有两者的就是二叉查找树,以及后面的散列表。

3. 二叉查找树

在这里插入图片描述
使用二叉查找树的算法的运行时间取决于树的形状,而树的形状又取决于被插入的先后顺序,在最好的情况下,一棵含有N个节点的树是完全平衡的,每条空链接和根节点的距离都是lgN,在最坏的情况下,搜索路径上可能有N个节点。

4. 平衡查找树

(1)2-3树
为了保证查找树的平衡性,我们需要一些灵活性,因此在这里我们允许树中的一个结点保存多个键。确切地说,我们将一颗标准的二叉查找树中的节点称为2-结点(含有一个键和两条链接),而我们现在引入3-结点,它含有两个键和3条链接。左连接指向的2-3树种的键都小于该结点,中链接指向的2-3树中的键都位于该节点的两个键之间,右链接指向的2-3树中的键都大于该节点。
查找
要判断一个键是否在树中,我们先将它和根节点中的键比较。如果它和其中任意一个相等,查找命中。否则我们就根据比较的结果找到指向相应区间的链接,并在其指向的子树中递归地继续查找。
插入
我们使用2-3树的主要原因就在于它能够在插入后继续保持平衡。
向2-结点中插入新键
如果未命中的查找结束于一个2-结点,事情就好办了,我们只要把这个2-结点替换为一个3-结点。将要插入的键保存在其中即可。
向3-结点中插入新键
在这里插入图片描述
为了将新键插入,我们先临时将新键存入该结点中,使之成为一个4-结点。很容易将它转换为一棵由3个2-结点组成的2-3树,其中一个结点含有中键(根节点),一个结点含有3个键中的最小值(和根节点的左连接相连),一个结点含有3个键中的最大值(和根节点的右链接相连)。这棵树既是一棵含有3个节点的二叉查找树,同时也是一棵完美平衡的2-3树。插入前树的高度为0,插入后树的高度为1。

向一个父节点为2-节点的3-节点中插入新键
在这里插入图片描述
我们先像上面那样构造一个临时的4节点并将其分解,但此时我们不会为中键创建一个新节点,而是将其移动到原来的父节点上。父节点也从一个2节点转换为了一个3节点。另外,这次转换也并不影响2-3树的主要性质,树仍然是有序的,因为中键被移动到父节点中去了,树仍然是完美平衡的。

向一个父节点为3-节点的3-节点中插入新键

在这里插入图片描述
假设未命中的查找结束于一个父节点为3-节点的节点。我们再次和刚才一样构造一个临时的4-节点并分解它。然后将它的中键插入它的父节点中。但父节点也是一个3-节点,因此我们再用这个中键构造一个新的临时4-节点,然后在这个节点上进行相同的交换。即分解这个父节点并将它的中键插入到它的父节点中去。推广到一般情况,我们就这样一直向上不断分解临时的4-节点并将中键插入更高层的父节点,直到遇到一个2-节点并将它替换为一个不需要继续分解的3-节点,或者是达到3-节点的根。

分解根节点

在这里插入图片描述
如果从插入节点到根节点上全都是3-节点,我们的根节点最终会变成一个临时的4-节点。此时我们可以按照向一个3-节点的树中插入新键的方法处理这个问题。

局部变换

将一个4-节点分解为一棵2-3树可能有6中情况,如下图所示。

在这里插入图片描述
在一棵大小为N的2-3树中,查找和插入操作访问的节点必然不会超过lgN个。因此我们可以确定2-3树在最坏的情况下仍然有较好的性能,任何查找或者插入的成本都肯定不会超过对数级别。
但是,我们和真正的实现还有一段距离。尽管我们可以用不同的数据类型表示2-节点和3-节点,但是我们需要维护两种不同类型的节点,实现这些不仅需要大量的代码。而且它们所产生的额外开销可能会使算法比标准的二叉查找树更慢。

猜你喜欢

转载自blog.csdn.net/weixin_43928720/article/details/102768569
今日推荐