数据结构之查找(面试专用)
本篇博客主要用于对查找方面的数据结构做一个简单的介绍,能满足面试的时候问的问题深度即可,所以不会给出代码实现。
一、静态查找表
静态查找表主要满足一下两点:
a.查找某个“特定的”数据元素是否在查找表中;
b.检索某个“特定的”数据元素的各种属性。
方法 | 特点 | 时间复杂度 |
顺序查找 | 逐个比较,等概率比较 | O(n) |
二分查找 | 前提是序列有序 | O(logn) |
次优查找 | 不等概率,优先查找概率大的 | - |
索引顺序查找 | 分块有序;二分查找确定分块,块内顺序查找 | - |
二、动态查找表
动态查找表相比于静态查找表有两个不同的特点:
a.在查找表中查询一个数据元素,如果不存在则插入查找表中;
b.从查找表中删去某个数据元素。
1.二叉排序树
关于二叉排序树的详细讲解在上一篇博客中已经讲的很详细了,有兴趣的可以参考上篇博客,这里就不在赘述。
2.平衡二叉树
(1)定义
平衡二叉树(Balanced Binary Tree或Height-Balanced Tree)又称AVL树。它或者是一棵空树,或者是具有下列性质的二叉树;它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1.
(2)为什么需要AVL树
我们知道,在极端情况下,建立起来的二叉排序树有可能变成单支树,这种情况下,在二叉排序树下进行查找时的效率降低到了单链表的查找,时间复杂度为O(logn)。最根本原因在于树的左右子树验证失衡导致的。所以需要AVL树来平衡左右子树。
(3)操作
由于AVL树左右子树深度差绝对值不超过1这个限制,所以当向AVL树中插入节点时,很多时候需要进行调整。一般情况下,假设由于在二叉排序树上插入节点而导致失衡的最小子树根节点的指针为a,即a是离插入节点最近,且平衡因子绝对值超过1的祖先节点,则失去平衡后进行调整有以下四种情况:
3.B-树
B-树是一种平衡的多路查找树,它在文件系统中很有用。B-树的定义很复杂,这里就不介绍了,然后举一个例子来说明B-树的组织。
在B-树上进行查找包含两种基本操作:(1)在B-树中找节点;(2)在节点中找关键字。由于B-树通常存储在磁盘上,则前一次查找操作是在磁盘上进行的,而后一查找操作是在内存中进行的,即在磁盘上找到指针p所指节点后,先将节点中的信息读入内存,然后再利用顺序查找或者折半查找查询等于K的关键字。显然,在磁盘上进行一次查找比在内存中进行一次查找耗费时间多得多,因此,在磁盘上进行查找的次数,即待查关键字所在节点在B-树上的层次数,是决定B-树查找效率的首要因素。
4.B+树
B+树应文件系统所需而出的一种B-树的变形树。一棵m阶的B+树和m阶的B-树的差异在于:
a.有n棵子树的节点含有n个关键字;
b.所有的叶子节点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接;
c.所有的非终端节点可以看成是索引部分,节点中仅含其子树中的最大(或最小)关键字。
B+树有点类似于静态查找表中的索引顺序表。
5.键树
键树比较好理解,就类似于我们字典的组织方式。
假设有如下16个关键字的集合:{CAI, CAO, CHA, CHANG, CHAO, CHEN, WEN, WANG, WU, ZHAO, LI, LAN, LONG, LIU, YUN, YANG},则其生成的键树如下:
三、哈希
1.哈希表
(1)哈希函数
哈希函数就是在记录的存储位置和它的关键字之间建立的一个确定的对应关系。
a.哈希函数是一个映像,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表长允许范围之内即可;
b.对不同关键字可能得到同一哈希地址,即key1!=key2,而f(key1)=f(key2),这种现象称冲突。
然而,在一般情况下,冲突只能尽可能地少,而不能完全避免。
2.哈希函数(杂凑函数)
常见的构造哈希函数的方法有:
(1)直接定址法
取关键字或关键字的某个线性函数值为哈希地址。即H(key)=key或H(key)=a*key+b,其中a、b为常数。
(2)数字分析法
假设关键字是以r为基的数,并且哈希表中可能出现的关键字都是实现知道,即可取关键字的若干数位组成哈希地址。
(3)平方取中法
取关键字平方后的中间几位为哈希地址。
(4)除留取余法
去关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址,即H(key)= key MOD p, p<=m。
3.处理冲突的方法
(1)开放定址法
a.线性探测再散列
b.二次探测再散列
c.伪随机探测再散列
(2)再哈希法
即在同义词(具有相同函数值的关键字对同一个函数而言为同义词)产生地址冲突时计算另一个哈希函数地址,直到冲突不再发生。
(3)链地址法
将所有关键字为同义词的记录存储在同一线性链表中。