总结自b站青岛大学王卓老师的讲课,感觉是最容易理解的数据结构课了!
1.应用范围:
顺序表
或线性链表
表示的静态查找表
无序
2.数据元素定义、顺序表的表示:
typedef struct{
KeyType key; //关键字域
…… //其他域
}ElemType;
typedef struct{
ElemType *R; //表基址
int length; //表长
}SSTable; //Sequential Search Table
SSTable ST;
3.顺序表中进行顺序查找
3.1使用哨兵优化
在顺序表ST中查找值为key的数据元素,从最后一个元素开始往前找:
原始代码为:
int Search_Seq(SSTable ST,KeyType key){
//若成功返回其位置信息,失败返回0
for(i=ST.length; ST.R[i].key!=key && i>=1; --i);//此时每次循环需要进行2次比较
if(i>0) return i;
else return 0;
}
为了防止每次循环需要进行2次比较,可以使用哨兵
(监视哨
)进行优化:即将待查关键字key存入表头0号位置,免去每次循环中比较是否查找完毕。
int Search_Seq(SSTable ST,KeyType key){
ST.R[0].key=key; //将待查找关键字放入表头
for(i=ST.length; ST.R[i].key!=key; --i);//此时每次循环只需进行1次比较
return i;
}
3.2时间效率的分析
(1)时间复杂度O:(n)
(2)ASL = (1+2+…+n)/n = (n+1)/2
(3)空间复杂度:O(1)
3.3记录的查找概率不同时
(1)若事先知道表中各结点的查找概率,根据它们的分布情况,将表中结点按查找概率由小到大地存放,以便提高顺序查找的效率。
(2)若无法预测各元素的查找概率,每当查找成功,就将找到的结点和其后继(若存在)结点交换。这样,使得查找概率大的结点在查找过程中不断往后移,便于在以后的查找中减少比较次数。
3.4顺序查找法的特点
(1)优点:算法简单,逻辑次序无要求,不同存储结构均适用
(2)缺点:ASL太长,时间效率低
1.基本思想:每次将待查找记录所在区间缩小一半。
2.算法实现
2.1 非递归算法
设表长为n,low、high和mid分别指向待查找元素所在区间的上界、下界和重点,key为要查找值:
int Search_Bin(SSTable ST,KeyType key){
low=1,high=ST.length; //设置区间初值
while(low<=high){
mid=(low+high)/2;
if(ST.R[mid].key==key) return mid; //找到待查元素
else if(key<ST.R[mid].key) high=mid-1; //继续在前半区间查找
else low=mid+1; //继续在后半区间查找
}
return 0; //顺序表中不存在待查元素
}
2.2 递归算法
int Search_Bin(SSTable ST,KeyType key,int low,int high){
if low > high return 0;
mid=(low+high)/2;
if(key==ST.elem[mid].key) return mid;
else if(key<ST.elem[mid].key)
Search_Bin(ST,key,low,mid-1);
else
Search_Bin(ST,key,mid+1,high);
}
3.性能分析
3.1 判定树
根据二分查找的先后次序和所在区间,生成对应的判定树。
3.2 查找成功情况
圆形节点代表查找成功的情况,对应的比较次数为圆形节点的深度,由完全二叉树性质可知最多比较[log2N] +1能够找到。
3.3 查找失败情况
矩形节点代表查找失败的情况,比较次数小于等于[log2N] +1。
3.4 计算ASL
ASL = ((n+1)/n * log2(n+1))-1。
对于任意表长n大于50的有序表,其折半查找的平均查找长度近似为:ASL ≈ log2(n+1)-1。
4.算法特点
(1)优点:效率较高。
(2)缺点:只适用于有序表,且限于顺序存储结构(对线性链表无效)。
1.使用条件
(1)将表分为几块,且块内可以有序或无序(无序时称为分块有序
);
即若i
(2)建立索引表(每个节点含有最大关键字域
和指向本块第一个结点的指针
,且按关键字有序
)
2.查找过程
(1)先确定待查记录所在块(使用顺序或折半查找)
(2)在在块内查找(顺序查找,一般块内无序,方便插入删除)
3.性能分析
(1)ASL = Lb (查找索引表的ASL) + Lw (块内查找的ASL) ≈ log2(n/s + 1) + s/2
4.特点
(1)优点:插入和删除比较容易,无需进行大量移动
(2)缺点:要增加一个索引表的存储空间,并对初始索引表进行排序运算
(3)适用情况:如果线性表要快速查找且经常动态变化,可采用分块查找。