顺序查找
(线性查找)
1.一般线性表的顺序查找
引入哨兵,使得循环时不必判断是否越界
ST.elem[0]=key;
for(i=ST.TableLen;ST.elem[i]!=key;--i);
return i;
ASL成功=(n+1)/2
ASL失败=n+1
2.有序表的顺序查找
查找判定树
ASL成功=(n+1)/2
ASL失败=n/2+n/(n+1)
折半查找
(二分查找)
仅适用于有序的顺序表
int Binary_Search(SeqList L, ElemType key)
{
int low=0, high=L.TableLen-1, mid);
while(low<=high){
mid=(low+high)/2;
if(L.elem[mid]==key)
return mid;
else if(L.elem[mid]>key)
high=mid-1;
else
low=mid+1;
}
return -1;
}
判定树
ASL成功=log2(n+1)-1
分块查找
(索引顺序查找)
吸取了顺序查找和折半查找各自的优点,即有动态结构,又适于快速查找。
基本思想:将查找表分为若干子块,块内无序,块间有序。前一个块中的最大关键字小于后一块中所有记录的关键字。建立一个索引表,索引表中的每个元素含有各块的最大关键字和各块中的第一个元素的地址,索引表按关键字有序排序。
B树
(多路平衡查找树)
一棵m阶B树或为空树,或为满足如下特性的m叉树
1.树中每个节点最多有m课子树(m-1个关键字)
2.若根节点不是终端节点,则至少有两棵子树
3.除根节点外的所有非叶节点至少有⌈m/2⌉棵子树(⌈m/2⌉-1个关键字)
4.非叶结点的结构为
________________________________
| n | P0 | K1 | P1 | K2 | P2 |......| Kn | Pn|
————————————————————————————————
n个关键字,n+1个指针
Ki为关键字且按顺序排列
Pi为指向子树的指针
Pi-1所指子树的值均小于Ki,Pi所指子树的指均大于Ki
n为结点中关键字的个数
5.所有叶节点都出现在同一层次上,且不带信息,实际不存在指针为空
B树.JPG
B树的高度
磁盘的存取次数
(不包括最后的不带信息叶结点那层)
B树的查找
1.在B树中找结点
2.在结点内找关键字
由于B树常存储在磁盘上,因此前一个查找操作是在磁盘上进行的,后一个是在内存中进行。
查找到某个节点后,先在有序表中进行查找,若找到则查找成功,否则按照对应的指针信息到所指的子树中去查找,查找到叶结点时,则说明树中没有对应关键字,查找失败。
B树的插入
1.定位:利用B树查找法,找出插入该关键字的最低层中的某个非叶节点
2.插入:插入后节点的关键字数小于m则可直接插入,否则对结点进行分裂
3.分裂:取一个新结点,在插入key后的原节点从中间位置将其中的关键字分为两部分,左边的部分留在原节点,右边的部分去新结点,中间位置(m/2向上取整)的节点插入到父节点,若导致父节点个数大于m-1,则继续分裂直至这个过程到根节点为止,此时会导致B树高度增加1
pic
B树的删除
将被删除关键字Ki与它的左或右子节点中最相近的关键字Ki'替代它,再递归删除Ki'
有以下几种情况
1.若其所在节点的关键字数大于⌈m/2⌉-1,则直接删除
2.若其所在节点的关键字数等于⌈m/2⌉-1,兄弟节点关键字数大于⌈m/2⌉-1,父节点对应关键字加到所在节点中,兄弟节点中的一个关键字移到父节点
3.若其所在节点的关键字数等于⌈m/2⌉-1,左右兄弟节点关键字数也均等于⌈m/2⌉-1,就把父节点中对应的那个关键字加到所在子节点与其某个兄弟节点合并后的节点中
合并过程会导致父节点中关键字减少,若是根节点个数减少到0,则删除根节点,将合并后的节点作为新的根。若非根节点减少到⌈m/2⌉-2,则又要与它自己的兄弟节点进行调整或合并操作。
图解
https://www.jianshu.com/p/a858bb15cbf0
B+树
1.树中每个节点最多有m课子树
2.若根节点不是终端节点,则至少有两棵子树,除根节点外的所有非叶节点至少有⌈m/2⌉棵子树
4.结点的子树个数与关键字个数相同
5.所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来
6.所有分支节点中仅包含它的各个子节点中关键字的最大值
两种查找方式
B+.JPG
网友评论