线性表查找——查找表


线性表存储结构

//数据类型
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.分块查找

将序列分成几个区间,区间的关键字按一定顺序有序,块内数据不需要有序。
所谓快间有序,即每一个块中所有记录的关键字值均大于(升序)或小于(降序)前一块的所有的关键字的值。索引表的数据元素分别记录每一块的最大关键字和起始地址。
查找关键字的时候,先确定在哪个区间中查找,找到确定的块,在块中顺序查找关键字。

猜你喜欢

转载自blog.csdn.net/zxj20041003/article/details/130019996