8.1开场白+8.2查找概论
8.3顺序表查找
8.3.1顺序查找算法
8.3.2顺序表查找优化
8.4有序表查找
8.4.1折半查找
8.4.2插值查找
8.4.7裴波那契查找
8.5线性索引查找
8.5.1稠密索引
8.5.2分块索引
8.5.3倒排索引
8.6二叉排序树
8.6.1二叉排序树查找操作
8.6.2二叉排序数插入操作
8.6.3二叉排序树删除操作
8.6.4二叉排序树总结
8.7(平衡二叉树)AVL树
8.7.1平衡二叉树实现原理
8.7.2平衡二叉树实现算法
8.8多路查找树
8.9散列表查找(哈希表)概述
8.10散列函数的构造方法
8.11处理散列冲突的方法
8.12散列表查找实现
8.12.1散列表查找算法实现
8.12.2散列表查找性能分析
8.1开场白+8.2查找概论
1.查找表:静态查找表+动态查找表
a.静态查找表:查询某个特定的数据元素是否在查找表中+检索某个特定的数据元素和各种属性
b.动态查找表:查找时插入元素,查找时删除元素
2.静态查找----线性结构组织数据+顺序查找法+对于主关键字排序可以使用折半查找
3.动态查找----二叉排序树的查找技术
8.3顺序表查找
- 顺序查找过程:从表中第一个开始,逐个进行记录的关键字和给定值比较,若某个记录关键字和给定值相同则查找成功,如果找到最后一个,其关键字和给定值都不同,则查找失败
- 8.3.1顺序查找算法代码
/*顺序查找,a为数组,n为要查找的数组长度,key为要查找的关键字*/
int Sequential_Search(int *a,int n, int key)
{
int i;
for(i=1;i<=n;i++)
{
if(a[i]==key)
{
return i;
}
}
return 0;
}
由于上面的查找中每次都要i<=n的判断,实际上设置一个哨兵即可,如下代码
- 8.3.2顺序表查找优化
/*有哨兵顺序查找*/
int Sequential_Search2(int *a,int n,int key)
{
int i;
a[0]=key; //设置a[0]为关键字值,称为“哨兵”
i=n; //循环从数组尾部开始
while(a[i]!=key)
{
i--;
}
return i; //返回0则查找失败
}
此代码从尾部开始查找,a[0]=key,如果在a[i]中有key则返回i值,查找成功。否则一定在最终的a[0]处等于key,此时返回0,说明查找失败
8.4有序表查找
- 8.4.1折半查找
思想:折半查找的前提是线性表中的记录必须是关键码有序(通常从小到大)。在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右边区继续查找。不断重复上述过程,直到查找成功,或查找区域无记录,查找失败
参考代码:折半查找时间复杂度o(logn)
/*折半查找*/
int Binary_Search(int *a,int n, int key)
{
int low,high,mid;
low=1; //定义最低下标为记录首位
high=n; //定义最高下标为记录末位
while(low<=high)
{
mid=(low+high)/2; //折半
if(key<a[mid]) //若查找值比中指小
high=mid-1;
else if(key>a[mid]) //若查找值比中指大
low=mid+1; //最底下标调整到中位下标大一位
else
return mid; //若相等则说明mid即为查找到的位置
}
return 0;
}
查找过程如下:
用二叉树示意如下图:
- 8.4.2插值查找
插值查找时根据要找的关键字key与查找表中最大最小的关键字比较后的查找方法,其核心在于插值公式如下图:
将折半查找的第8行代码改为:mid=low+(high-low)*(key-a[low])/(a[high]-a[low]);
- 8.4.3裴波那契查找
参考代码:
//裴波那契查找
int Fibonacci_Search(int *a,int n,int key)
{
int low,high,mid,i,k;
low=1; //定义最低下标为记录首位
high=n; //定义最高下标为记录末位
k=0;
while(n>F[k]-1) //计算n位于裴波那契数列的位置,F[k]就是裴波那契数列,a[n]就是要查找的数列
k++;
for(i=n; i<F[k]-1; i++) //将不满的数值补全
a[i]=a[n];
while(low<=high)
{
mid=low+F[k-1]-1; //计算当前分隔的下标
if(key<a[mid]) //若查找记录小于当前分隔记录
{
high=mid-1; //最高下标调整到分隔下标mid-1处
k=k-1; //裴波那且数列下标减一位
}
else if(key>a[mid]) //若查找记录大于当前分隔记录
{
low=mid+1; //最低下标调整到分隔下标mid+1处
k=k-2; //裴波那契数列下标减2位
}
else
{
if(mid