C语言-线性表的查找(Linear Table Search)

线性表的查找
静态查找:只找不改
动态查找:边找边改
无序查找:顺序查找
有序查找:折半查找
分块查找
哈希表?

1.顺序查找(无序查找)

  • 顺序查找(Sequential Search) 的查找过程为:从表的一端开始,依次将记录的关键字和给定 值进行比较,若某个记录的关键字和给定值相等,则查找成功;反之,若扫描整个表后,仍未找 到关键字和给定值相等的记录,则查找失败。
算法7.1 顺序查找

int a[n]={0,3,4,12,8,6,34,97,14,22,66};//查找表,a[0]不存储数据

int SequentialSearch(int key,int a[n])
{
    i=1;
    while(i<=n&&a[i]!=key)//注意此处每循环一次需要判断2个条件
    {
        i++;
    }
    
    if(i<n)
        return i;//找到了
    else 
        return 0;//没找到

    return;
}
  • 优化顺序查找:设置哨兵。将要找到关键字key放在表的第一个位置,设置成哨兵。从后往前查找,这样的话每次循环只需要对一个条件进行判断。(若将哨兵设置在表尾,从前往后查找表也是可以的)
算法7.2 设置哨兵的顺序查找

int a[n]={0,3,4,12,8,6,34,97,14,22.66};//查找表,a[0]不存储数据

int SequentialSearch(int key,int a[n])
{
    i=1;
    a[0]=key;//将表第一个位置设置成哨兵
    
    while(a[i]!=key)//注意此处每循环一次只需要判断1个条件
    {
        i--;
    }
    
    if(i!=0)
        return i;//找到了
    else 
        return 0;//没找到

    return;
}
  • 算法7.1与算法7.2的时间复杂度都是一样的,把整个表走一遍,时间复杂度为O(n),但是算法7.2通过设置哨兵,减少每一次循环的判断条件个数,能使得n>1000时,查找的平均时间几乎减少一半。

2.折半查找(有序查找)

  • 折半查找(Binary Search)也称二分查找,它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。在下面及后续的讨论中,均假设有序表是递增有序的。
#include <stdio.h>

int BinarySearch(int a[10],int key)
{
	int low,high,mid;
	
	low=0;//初始时low等于表头 
	high=9;//初始时high等于表尾 
	
	while(low<=high)
	{
		mid=(low+high)/2;
		
		if(a[mid]==key)
		{
			printf("\nlow=%d mid=%d high=%d\n",low,mid,high); 
			printf("\nkey=%d,位置是%d",key,mid);
			return mid;
		}
		else if(a[mid]>key)//key小于a[mid],则往mid的左边找 
		{
			printf("\nlow=%d mid=%d high=%d\n",low,mid,high); 
			printf("a[mid]>key\n");
			high=mid-1;
		}
		else if(a[mid]<key)//key大于a[mid],则往mid的右边找 
		{
			printf("\nlow=%d mid=%d high=%d\n",low,mid,high); 
			printf("a[mid]<key\n");
			low=mid+1;
		}
	}
	printf("\n查找失败!\n");
	return -1; 
}

int main()
{
	int i;
	int a[10]={1,4,5,7,9,12,24,45,56,88};
	int key=24;
	
	printf("a[11]=");
	for(i=0;i<10;i++)
	printf("%d ",a[i]);
	printf("\n");
	
	BinarySearch(a,key);
	
	return 0;
}

执行结果:

a[11]=1 4 5 7 9 12 24 45 56 88

low=0 mid=4 high=9
a[mid]<key

low=5 mid=7 high=9
a[mid]>key

low=5 mid=5 high=6
a[mid]<key

low=6 mid=6 high=6

key=24,位置是6
--------------------------------
Process exited after 0.03012 seconds with return value 0
请按任意键继续. . .
  • 折半查找判定树
  • 由此可以得出折半查找的时间复杂度O(log2n)

3.分块查找

  • 分块查找是将数据元素分块放置块与块之间有序,块内无序。意思就是说第一块的max(element)< 第二块的max(element)< 第三块的max(element)
  • 所以我们根据数据表建立,一个索引表,能够根据索引表直观的看出块的位置信息与块的最大元素
  • 所以如何查找?
  • 分块查找是先在有序的块之间,确定key所在的块的位置,然后再到该确定的块中去找key
  1. 先查找块,用的是折半查找,快速的定位key在哪一块
  2. 确定哪一块后,在该块中进行顺序查找
  • 假设我们要在图7.4所示的表中查找元素"38"
  1. 根据索引表我们知道22 ≤ 38 ≤ 48,所以要找的元素"38"在第二个块中
  2. 我们在到第二块中去查找"38",查找到"38"的坐标是10
  • 所以分块查找的性能介于顺序查找折半查找之间

注:还有其他的有序查找算法,如斐波那契查找插值查找等时间复杂度与折半查找法一致,都是O(log2n),再次不多介绍


总结


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Attract1206

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值