查找
线性结构
查找表的数据结构定义
typedef struct{
ElemType *elem;
int TableLen;
}SSTable;
折半查找(二分查找)
//非递归
int Binary_Search(SeqList L,ElemType key){
int low=0,high=L.TableLen-1,mid;
while(low<=high){ //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;
}
/* 递归
递归结束条件 low>high
递归开始 当前的mid不等于待查找结点,需要递归遍历前半部分表或者后半部分表,改变的是数据的起始和结束位置(low high)
*/
int Binary_Search(SSTable ST,ElemType key,int low,int high){
if(low>high) //递归结束的条件
return 0;
mid=(low+high)/2;
if(key>ST.elem[mid]) //在后半部分表中查找
Binary_Search(ST,key,mid+1,high);
else if(key<ST.elem[mid]) //在前半部分表中查找
Binary_Search(ST,key,low,mid-1);
else
return mid;
}
掌握:折半查找过程,分解每次取得数值 low/high/mid
构造折半查找判定树,分析平均查找长度
【 若有序序列有n个元素,对应的判定树有n个圆形的非叶结点和n+1个方形的叶节点,平衡二叉树,二叉排序树(左<根<右) 】
课后习题!!!
顺序查找
int Search_Seq(SSTable ST,ElemType key){
ST.elem[0]=key; //将位置0的地方设为key“哨兵”
int i=1; //从前向后遍历(课本采用从后向前遍历)
while(i<ST.TableLen)
if(ST.elem[i]!=key)
i++;
return i;
}
分块查找
树形结构
二叉排序树
二叉平衡树
B树
图例 Page 285 + Notability笔记
磁盘读取、多路平衡查找树
高度(磁盘存取次数)
一棵n个关键字、高度为h、阶数为m的B树
B树中每个结点最多m棵子树,m-1个关键字;n个关键字有n+1个子树(n+1种范围查找数据)
最小高度:每个结点关键字个数尽可能满
最大高度:每个结点关键字个数尽可能少
查找
类似于二叉查找树,子树0<关键字1<子树1<关键字2<子树2<……
每个结点都是多个关键字有序表,查找结点的多路分支
例如:查找结点42的过程
查找根结点22,有42>22,向22的右分支查找,有36<42<45,位于中间子树,继续向下,找到42;如果找到的是叶结点(空指针)表示查找失败,没有对应关键字,查找失败。
插入
寻找插入位置:检索到适合插入的最底层的终端结点
判断结点中关键字的个数:
若插入后结点关键字个数<m,直接插入
若插入后结点关键字个数>m-1,结点分裂
分裂方法
插入新结点后,将原来的结点从中间位置开始划分,产生一个新结点
原结点=左半部分;新结点=右半部分;中间位置插入父结点;
如果父结点还是不满足B树条件,继续分裂,直到根结点,此时B树高度+1
删除
被删除关键字k不在终端结点
用直接前驱代替(关键字k左侧指针指向的最右下元素)/ 直接后继代替(关键字k右侧指针指向的最左下元素)
被删除关键字k在终端结点
关键字删除后,符合B树,直接删除k
关键字删除后,不符合B树
兄弟够借(关键字删除后左右兄弟符合B树定义)
右兄弟:关键字k后继——>k,关键字k后继的后继——>k后继
左兄弟:关键字k前驱——>k,关键字k前驱的前驱——>k前驱
兄弟不够借(关键字删除后左右兄弟不符合B树定义)
将k删除后的左兄弟/右兄弟与k的双亲结点进行合并,结点会减少;再比较双亲结点是否还符合B树
B+树
图例 Page 288 + Notability笔记
关系数据库MySQL
n个关键字有n个子树(n个子树中各取1个分支结点作为索引,在叶子结点中依旧出现)
分支结点=索引结点;子树中最大关键字的副本
查找过程:最小关键字开始顺序查找;(指向关键字最小叶结点的头指针)
从根结点到叶结点路径;(指向根结点的头指针)
散列结构
散列表
选取散列函数构造(查找表中的关键字映射到对应的地址的函数)【散列表存放这个映射关系】
映射过程中会产生冲突——>选择合适的处理冲突方法
开放定址法:数学递推公式【主要确定增量di】
拉链法:所有同义词存储在一个线性链表中
查找性能分析
查找过程与构造散列表过程基本一致;
查找成功/失败:都需要统计每个关键字的比较次数(拉链法)
成功情况只要统计给定关键字的比较次数;给定关键字个数
失败情况每个链地址中失败的比较次数;链地址单元个数(给定关键字个数+1)
查找效率
散列函数
处理冲突方法
装填因子=散列表中记录数/散列表长度【散列表中记录越多,冲突可能性越大,查找效率越低】
掌握:散列表构造
冲突处理方法(各种方法处理过程)
查找成功和失败的平均查找长度
散列查找的特征和性能分析
课后习题!!!
核心考点—平均查找长度ASL
设有n个数据元素,每个元素的查找概率为Pi 查找成功的比较次数Ci
不在此集合中的数据元素分布在由这n个元素间隔构成的n+1个子集合中,每个子集合元素的查找成功的概率为Qj 查找不成功的比较次数Cj
分别相乘再累加 / 查找成功(失败)元素个数
= 平均查找长度(成功/失败)