一、基本概念
静态查找:无需动态地修改查找表。(适合顺序查找、折半查找、散列查找)
动态查找:需对查找表进行动态地插入或删除。(适合二叉树的查找、散列查找)
二、线性结构的查找
1. 顺序查找 (线性的链表只能顺序查找)
- 无序线性表:从一端到另一端逐个检查;
- 有序线性表:关键字有序,不用检查到末尾就可以得知失败。
2. 折半查找
与中间元素比较,确定查找元素在其前方/后方,缩小比较范围;重复以上操作。
其过程可用二叉树描述(判定树),此树是平衡二叉树。
3. 分块查找 / 索引顺序查找
将查找表分为若干块,块间有序,块内无序;建索引表存储各块最大关键字和块中第一个元素地址,索引表按关键字排序。
查找时先查索引表找到对应块,然后在块内顺序查找。
三、树形结构的查找
1. 二叉排序树(BST、二叉查找树)
左子树结点值<根结点值<右子树结点值。
是一个动态树表,可通过插入和删除更新树表。查找效率取决于树高。
2. 平衡二叉树(AVL树)
插入和删除元素时保证各结点左右子树高度差不超过1,不平衡时调整最小不平衡子树。
- LL平衡旋转(右单旋转):在结点A的左孩子的左子树插入,则A的左孩子替代A,A替代A的右孩子
- RR平衡旋转(左单旋转):在A的右孩子的右子树插入,A的右孩子替代A,A替代A的右孩子
- LR平衡旋转(双旋):在A的左孩子的右子树插入C,则C左上旋到A的左子树,再右上旋到A
- RL平衡旋转(双旋):在A的右孩子的左子树插入C,则C右上旋到A的右子树,再左上旋到A
删除和插入类似,但删除后要先平衡调整,然后若找到第一个不平衡的结点C,则再上旋。
3. 红黑树
(对平衡二叉树的平衡标准放宽为2倍差,适合插入/删除操作多的)
根、叶为黑,无相邻红。结点到任意叶结点的黑结点数相同。
结论
- 根到叶结点的最长路径不大于最短路径的两倍。
- n个内部结点的红黑树高度h小于等于2log(n+1)
- 插入结点默认红色,连续红色则调整
插入时(导致两个红结点)
- 叔结点为黑:LR时先左旋再右旋,LL时右单旋;RL时先右旋再左旋,RR时左单旋。
- 叔结点为红:将父结点、叔结点变黑,爷结点作为新结点,如此向上循环。
删除时(导致黑高变化)
- x有两个孩子,则转换为只有一个孩子的情况处理
- 有一个孩子,则必为红色,将其转换为黑色替代x
- 红色且无孩子,直接删除
- 黑色且无孩子,若兄弟结点w不为黑要先将兄弟转黑(和父结点交换颜色并上旋)
- RL即w的红结点孩子是其爷结点的右孩子的左孩子,则先右旋再左旋,
- RR即w的红结点孩子是其爷结点的右孩子的右孩子,则左单旋
- w两个孩子都是黑色,可将x和w的黑色去掉,他们的父结点着黑作为新结点来循环
4. B树
(所有结点平衡因子均为0的多路平衡查找树)
- m阶的B树,除根结点外所有分支结点至少有⌈m/2⌉棵子树(⌈m/2⌉-1个关键字),至多有m棵子树。
- 非叶根节点至少2棵子树(1个关键字)
- 所有叶结点为同一层次、不带信息的结点,可视为查找失败。不算入树高。
查找:先找结点(磁盘上),然后在结点内找关键字(内存中)
插入:结点内关键字超出要进行“分裂”。
删除:结点内关键字不足要进行“合并”。
- 非终端结点(最低层非叶):先转换为终端结点,即用其前驱或后继代替。
- 终端结点:①直接删;②兄弟够借则兄弟替换双亲中关键字,使其下移;③兄弟不够借则合并兄弟,变为双亲结点关键字减一的问题。
5. B+树
(B树的变形树,数据库所需)
- 每个关键字对应一颗子树。分支结点至少有⌈m/2⌉棵子树(⌈m/2⌉个关键字)
- 非叶根节点至少2棵子树(2个关键字)
- 叶结点包含信息,非叶结点只作索引
查找:可从最小关键字开始顺序查找(叶结点依次检查),或从根结点开始多路查找。
四、散列结构--散列表 的查找
散列表是根据关键字而直接进行访问的数据结构。Hash(Key)=地址。
根据关键字集合特点选择适合的散列函数,常见有:
- 取关键字线性函数值a*key+b(适合关键字分布基本连续)
- 对关键字取余key%p。关键是根据表长m取≤m的合适的数p。
- 选取数码分布较均匀的若干位(适合已知关键字集合的)
- 取关键字的平方值的中间几位(适合关键字每位取值都不够均匀,或均小于地址所需位数)
冲突处理
- 1. 开放定址法 :用空闲地址存储同义词和非同义词表项。取定某一增量di,有 Hi=(H(key)+di)%m。(要逻辑删除,防止截断同散列地址的元素的地址,定期物理删除)
- 线性探测法:di=0,1,2…k (k<m-1)找到表中下一个空闲单元进行存储(产生堆积问题)
- 平方探测法:… (k≤m/2且m=4k+3的质数)(避免堆积问题,但不能检测所有单元)
- 双散列法:
- 伪随机序列法:di=伪随机序列
- 2. 拉链法:同义词在一个链表中存储,由散列表中唯一散列地址标识。(适合经常插入/删除)
性能分析
查找效率取决于:①散列函数 ②处理冲突发方法 ③装填因子(表中记录数n/散列表长m)