查找基本概念
术语 | 概念 |
---|---|
查找表 | 由同一类型的数据元素(或记录)构成的集合,是一种数据结构 |
查找 | 查找(Searching)特定元素是否在表中 |
查找成功/查找不成功 | 输出该记录/输出失败标志或失败位置 |
静态查找 | 只查找,不改变集合内的数据元素 |
动态查找 | 既查找,又改变(增减)集合内的数据元素 |
关键字 | 记录中某个数据项的值,可用来识别一个记录 |
主关键字 | 可以唯一(预先确定的记录的某种标志)标识一个记录的关键字,例如每条学生记录中都有的不同的学号 |
次关键字 | 识别若干记录的关键字,例如性别、年级 |
查找方法取决于表中数据的排列方式。
ASL(average search length 平均查找长度), 个人认为,算法的优劣用时间复杂度和空间复杂度衡量就行了,ASL也是一个类似的概念。
静态查找表
1、顺序查找
(Linear search,又称线性查找,用逐一比较的办法顺序查找关键字)
(1)对顺序结构进行线性查找
主要思路:在数组a[m]的前n(0<=n<m)个单元所储存的顺序表中,查找值为x的结点。若表中有x,查找成功,返回x的出巡地址(数组下标i);若表中没有x,查找不成功,返回一个无效地址NOTFOUND。其中,NOTFOUND是已定义的符号常数,例如:
#define NOTFOUND -1 //或 const int NOTFOUND=-1;
查找程序的主体部分如下:
从左向右查:
for(i=0;i<n;i++) if(a[i]==x) return i;
else return NOTFOUND;
从右向左查
for(i=n-1;i>=0;i--) if(a[i]==x) return i;
else return NOTFOUND;
等概率情况下,这种方法平均查找长度等于(n+1)/2,时间复杂度O(n),效率较低。
(2)使用监督元的顺序查找
主要思路:将待查关键字key存入表头或表尾(俗称“哨兵”),就可以加快执行速度。
int Search_Seq( SSTable ST , KeyType key ){ //查找与关键字相同的元素
ST.elem[0].key =key; //设立哨兵,可免去查找过程中的每一步都要检查是否查找完毕。当n>1000时,查找时间将减少一半,。
for( i=ST.length; ST.elem[ i ].key!=key; - - i );
return i; //找不到时返回值必为i=0
} // Search_Seq
2、折半查找
(又称二分查找或对分查找)
对单链表结构和双向链表结构不能折半查找,因为全部元素的定位职能从头指针开始。
int binary_search(element_type a[],element_type x,int n)
//数组a:存储的长度为n的有序表(这里是升序)
//x:是待查元素值
//返回值:某有效值或NOTFOUND
{int left,right,mid;
left=0,fight=n-1;
while(left<=right)
{
mid=(left+right)/2;
if(x==a[mid]) return(mid);
if(x<a[mid])right=mid-1;
else left=mid+1;
}
return(NOTFOUND);
}
算法的调用格式:
k=binary_search(b,y,m);
//在存储于数组b中长度为m的有序表中查找元素
...
时间复杂度:log2n
3、分块查找
(索引顺序查找)
特点:块间有序,块内无序
查找:块间折半,块内线性