查找
查找是与被查找元素的数据结构有关的,主要分为三类:线性表、树结构、哈希
1.线性表
顺序查找:效率比较低
折半查找:要求线性表有序,且可以随机访问(所以说链表不行)。
插值查找:折半查找每次都取1/2的位子,插值可以插入到适当的位子,减少次数。
2.树结构
树结构的查找效率跟树的结构有很大的关系。
二叉查找树:不平衡,最坏的情况就是顺序查找。
平衡二叉树:改进版。任一结构的左右子树的高度差小于1。
红黑二叉树:
- 性质 1:每个节点要么是红色,要么是黑色。
- 性质 2:根节点永远是黑色的。
- 性质 3:所有的叶节点都是空节点(即 null),并且是黑色的。
- 性质 4:每个红色节点的两个子节点都是黑色。(从每个叶子到根的路径上不会有两个连续的红色节点)
- 性质 5:从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。
由于平衡二叉树的构建会导致结点的裂变,这样插入的操作效率就很低。因此红黑二叉树就出来了。他保证了基本平衡,比排序二叉树的效率高,极端性比平衡二叉树低。但是插入和删除的效率比平衡二叉树高。实际应用大多采用红黑二叉树。
B树(B-tree):
- 1.定义任意非叶子结点最多只有M个儿子;且M>2;
- 2.根结点的儿子数为[2, M];
- 3.除根结点以外的非叶子结点的儿子数为[M/2, M];
- 4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
- 5.非叶子结点的关键字个数=指向儿子的指针个数-1;
- 6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
- 7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的
子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树; - 8.所有叶子结点位于同一层;
B-树的特性:
- 1.关键字集合分布在整颗树中;
- 2.任何一个关键字出现且只出现在一个结点中;
- 3.搜索有可能在非叶子结点结束;
- 4.其搜索性能等价于在关键字全集内做一次二分查找;
- 5.自动层次控制;
B+树(B+tree):
- 1.其定义基本与B-树同,除了:
- 2.非叶子结点的子树指针与关键字个数相同;
- 3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
- 5.为所有叶子结点增加一个链指针;
- 6.所有关键字都在叶子结点出现;
B+的特性:
- 1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
- 2.不可能在非叶子结点命中;
- 3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
- 4.更适合文件索引系统;
B树*(b*tree):
是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;
小结
B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于
走右结点;
B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键
字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;
3.哈希查找
常用的哈希算法:
- 直接地址法(参考java String类的hash函数实现)
- 除留取余法 (常用)
解决哈希冲突:
①开放地址法
冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。
②再哈希
③拉链法