线性表查找
线性表存储结构
//数据类型
typedef struct
{
int key;
int other;
}ElemType;
//关键字类型
typedef int KeyType;
typedef struct
{
ElemType* elem;//数组基地址
int length;//表长度
int size;//表的容量
}SSTable;
1.顺序查找O(n)
依序一个一个的查找
int SeqSearch1(const SSTable* st, KeyType k)
{
assert(st);
//数据元素从1号单元开始存放,0号单元留空
for (int i = st->length; i >= 1; i--)//存在条件判断,效率不佳
if (EQ(st->elem[i].key, k))return i;
}
去掉条件判断的改进
int SeqSearch2(const SSTable* st, KeyType k)
{
assert(st);
//在表st中查找关键字为k的记录,若找到,返回记录在数组中的下标,否则返回0
st->elem[0].key = k;//存放监视哨
int i = 0;
for (i = st->length; !EQ(st->elem[i].key, k); i--)//从表尾端开始向前查找
return i;
}
2.二分查找O(logn)
对有序的序列进行折半查找
//二分查找
int BiSearch1(const SSTable* st, KeyType k)//非递归
{
//用二分法在查找表st中查找关键字值为k的记录,若找到则返回在数组中的下标,否则返回为0
int left = 1, right = st->length;
while (left <= right)
{
int mid = (left + right) / 2;
if (EQ(st->elem[mid].key, k))return mid;//查找成功
else if (LT(st->elem[mid].key, k))left = mid + 1;//右半区间
else right = mid - 1;//左半区间
}
return 0;//查找失败
}
int BiSearch2(const SSTable* st, KeyType k,int left ,int right)//递归
{
if (left > right)return -1;
else
{
int mid = (left + right) / 2;
if (EQ(st->elem[mid].key, k))return mid;//查找成功
else if (LT(st->elem[mid].key, k))return BiSearch2(st, k, mid + 1, right);//右半区间
else return BiSearch2(st, k, left, mid - 1);//左半区间
}
}
不足:需要有序,排序花费时间大;不方便插入数据。
3.分块查找
将序列分成几个区间,区间的关键字按一定顺序有序,块内数据不需要有序。
所谓快间有序,即每一个块中所有记录的关键字值均大于(升序)或小于(降序)前一块的所有的关键字的值。索引表的数据元素分别记录每一块的最大关键字和起始地址。
查找关键字的时候,先确定在哪个区间中查找,找到确定的块,在块中顺序查找关键字。