【算法】查找-线性表的查找


一、顺序查找

顺序查找表又称线性查找,是最简单的查找方式,它适用于所有线性表,因为他的核心方法就是遍历整个表。

int SearchSequent(int *a, int n, int key){
	for(int i = 0; i < n; ++i){
		if(a[i] == key) return i;
	}
	return 0;
}

其实这个查找还可以优化,如果我们将线性表的第一个或者最后一个值空出,然后在查找的时候把他给放进去,随后直接遍历整个线性表,直到找到值才退出,因为我们已经把要找的值加到线性表里,所以不再需要考虑越界,减少了一半的程序量虽然他的时间复杂度仍然是O(n)。

int SearchSequent(int *a, int n, int key){
	a[0] - key;
	i = n;
	while(a[0] != key) --i;
	return i;
}

二、二分查找

上一个查找方法适用于所有线性表,从这里开始所有方法都只适用于排完序的顺序表,因为他们都涉及跳跃查找,并没有遍历所有元素,而这只有在线性表才能实现。二分查找就是在一个排过序的顺序表上(假设是升序),判断要查找的值和中间值大小关系,如果要找的值大于中间值,就说明要找的值如果存在那么必然在中间值的右边,反之亦然,随后再拿查找值和中间值右边数据的中间值比较,直到找完或者找到,该算法的时间复杂度是O(logn)

int BinarySearch(int *a, int n, int key){
	int low = 1, high = n, mid;
	while(low <= high){
		mid = (low + high) / 2 + 1;
		if(key < a[mid]) high = mid - 1;
		else if(key > a[mid]) low = mid + 1;
		else return mid;
	}
	return 0;`
}

三、插值查找

对于查值查找,我们只是把中间值mid的更新换了一个计算方式:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6247921e3e8645a8bf4dfaab2556fb1a.
当key是a[high]的一半的时候,显然这就是原先的mid,他的思想是如果我的key靠近low一点,那我就应该在靠近low的地方找找,这个算法的时间复杂度也是O(logn),这种算法在处理数据量大,数据分布均匀的时候效率会比二分查找好很多,但如果遇到极端数据如{1.1, 1.2, 1.3, 1.4, 100000},那么查找效果就很差

int InterpolationSearch(int *a, int n, int key){
	int low = 1, high = n, mid;
	while(low <= high){
		mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]) + 1;
		if(key < a[mid]) high = mid - 1;
		else if(key > a[mid]) low = mid + 1;
		else return mid;
	}
	return 0;`

四、斐波那契查找

通过将补全后的数组分为两块,子块又分别符合斐波那契数列,不如十个元素的数组,补成13,分成8、5,再比对,因为子块符合斐波那契,所以还可以继续分,直到找到或者找完。

int F = {0, 1, 1, 2, 3, 5, 8, 13, 21...}
int FibonacciSearch(int *a, int n, int key){
	int low = 1, high = n, k = 0;
	// 把数组补成斐波那契的形状
	while(n > F[k] - 1){
		++k;
	}
	for(int i = n; i < F[k]; ++i){
		a[i] = a[n];
	}
	while(low <= high){
		mid = low + F[k-1] + 1;
		if(key < a[mid]){
			high = mid + 1;
			--k;
		}else if(key > a[mid]){
			low = mid + 1;
			k -= 2;
		}else{
			if(mid <= n) return mid;
			return n;
		}
	}
	return o;
}

跳转系列文章目录


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值