第九章 查找
9.1 静态查找表
查找表:
由同一类型的数据元素构成的集合,可利用任意数据结构实现。松散的关系。
关键字:
可以标识列表中的一个或一组数据元素,若只能标识唯一的关键字则称为主关键字,反之称为次关键字
查找:
- 查找对象
- 查找范围
- 查找位置
查找的操作:
1.查找数据元素是否存在
2.检索数据元素的属性
3.在查找表中插入一个数据元素
4.删除一个数据元素
查找的方法:
- 比较式查找法
- 计算式查找法
平均查找长度:
9.1.1顺序表的查找
typedef struct student{
KeyType key;
}ElemType;
typedef struct{
ElemType *elem;
int length;
}ST;
//查找过程
//在顺序表ST中顺序查找其关键字等于key的元素,若找到,则函数值为该元素在表中的位置,否则为0
//EQ(a,b)函数是比较两个元素是否相等
int Search_Seq(SSTable ST, KeyType key){
ST.elem[0].key = key;
int i;
for(i = ST.length; !EQ(ST.elem[i].key, key); --i);
return i;
}
性能分析:
9.1.2有序表的查找
//二分查找
int Search_Bin(SSTable ST, KeyType key){
int low = 1, high = ST.length;
while(low<=high){
mid = (low+high)/2;
if(ST.elem[mid].key==key){
return mid;
}else if(ST.elem[mid].key>key){
high = mid - 1;
}else{
low = mid + 1;
}
}
return 0;
}
9.1.4索引顺序表的查找
块内无序,块间有序
分块查找基本过程
- 找到块
- 顺序查找法
9.2 动态查找表
9.2.1二叉排序树和平衡二叉树
二叉排序树或者是一颗空树,或者是具有如下性质的二叉树:
-
若它的左子树非空,则左子树上所有结点的值均小于根节点的值
-
若它的右子树非空,则右子树上所有结点的值均大于根节点的值
-
他的左右子树也分别为二叉排序树
ps:二叉排序树又称二叉查找树
1.二叉排序树的插入与生成:
- 先与根节点进行比较,比根节点小的往左子树比较,反之往右子树比较
- 在与子树的根节点进行比较,反复这个过程
- 发现当前根节点的左子树或者右子树为空,则插入到对应位置
2.二叉排序树元素的删除:
方法一:
- 删除操作首先要查找该节点是否存在,在哪个位置
- 若p为叶子节点,则可以直接删除
- 若p节点只有左子树,或只有右子树,则可将p的左子树或右子树直接改为其双亲结点f的左子树
- 若p节点既有左子树又有右子树,此时有两种处理方法:
- 首先找到p节点在中序遍历序列中的直接前驱s节点(s节点肯定没有右子树)
- 然后将p的左子树改为f的左子树,而将p的右子树改为s的右子树
方法二:
- 找到p节点在中序序列中的直接前驱s节点
- 用s节点的值替代p节点的值
- 将s节点删除
- 原s节点的左子树改为s的双亲节点q的右子树
3.二叉排序树的查找
就是二分查找
4.二叉排序树的查找性能
平衡二叉排序树:
- 左子树与右子树的高度之差的绝对值小于等于1(平衡因子绝对值小于等于1)
- 左子树和右子树也是平衡二叉排序树
若插入元素到右子树上,那么应该逆时针转