顺序查找,折半查找,插值查找,斐波那契查找和分块查找,c/c++描述

本文介绍了数组中查找算法的几种实现方式,包括顺序查找、折半查找、插值查找、斐波那契查找和分块查找。详细阐述了每种查找算法的原理和适用场景,并提供了相应的C++代码实现。顺序查找适用于未排序的线性表,折半查找和插值查找提高了效率,适合有序数组,而斐波那契查找利用斐波那契数列特性进一步优化,分块查找则通过索引加速查询。代码示例展示了各种查找算法的运行过程。
摘要由CSDN通过智能技术生成

  这里的查找,是指找到关键字等于给定值的记录在表里的位置,或者说关键字等于给定值的元素在数组里的下标,对于一维数组,关键字就是数组里元素的值。前提是数组里不能有重复的值。
  顺序查找,是把表里记录挨个与给定值比较,直到找到关键字等于给定值的记录。或者整个表里没有符合给定值的记录。要求表是线性表,顺序存储,或者链式存储。
  对于顺序存储的、关键字已经排序的表,可以采用折半查找。效率得以提高,但这样的表,不适于经常的插入删除表里记录。依据公式 : mid = (start + end) / 2 。start是表里记录的起点下标,end是表里记录的终点下标。
  类似于折半查找,我们也可以采用插值查找。其相对于折半查找,采用的 mid 值不同。依据公式 :
mid = start + (valForSearch - array[start])/(array[end] - array[start]) * (end - start) ,
valForSearch 是给定值。
  这个是初中就学过的知识,已知线段的两端点坐标,当把线段按比例分成两部分,求分段点的坐标,如图:
在这里插入图片描述

  在查找里能应用该公式的前提是,始终保证:
start <= mid <= end , array[start] <= array[mid] <= array[end] 。
否则对于 array[start] < valForSearch < array[start + 1] 的情况。程序会出错 。
  同理,对于斐波那契查找的算法,其思路是依据了斐波那契数列的性质:
Fibonacci[ n ] = Fibonacci[ n - 1 ] + Fibonacci[ n - 2 ]. 把表里记录数补全增加到等于最临近的斐波那契数列的那一项,然后把表分成两部分,一部分含有Fibonacci[ n - 1 ] 项,另一部分含有
Fibonacci[ n - 2 ] 项,比较给定值在哪一区间里,按Fibonacci数列递减的方向,缩小待比较的表记录区间。直到表里记录数小于等于 2 项。同样要警惕表里没有给定值的情况。当 start + 1 = end ,且
array[start] < valForSearch < array[end] 时,结束循环,直接得判定结果。
  综上所述,还是折半查找最为稳妥。mid 值的求法,依赖外界因素最少,最可靠。
  然后是分块查找,首先要把表里记录的索引,即数组的下标,分块,依据元素值的大小。块之间是有序的,块内部是无序的。结合折半查找和顺序查找,也可以加快表的查询速度。同时,减小了建立索引的工作量。
  以下是所有代码,程序建立思路如上所述,先是main函数所在源文件:

#include<iostream>
using namespace std;
#define MAXSIZE 30

extern void sequentialSearch(int array[],int length,int valForSearch);
extern void binarySearch(int array[], int length, int valForSearch);
extern void interpolationSearch(int array[], int length, int valForSearch);
extern void FibonacciSearch(int array[], int length, int valForSearch);
extern void blockSearch(int array[], int length, int valForSearch);

int main() {
	int arrayA[] = {3,6,2,10,1,8,100,7,4,9};
	sequentialSearch(arrayA,10,5);
	cout << endl;

	int arrayB[] = {1,2,3,4,5,6,7,8,10,11};
	binarySearch(arrayB,10,9);
	cout << endl;
	interpolationSearch(arrayB,10,9);
	cout << endl;

	int arrayC[MAXSIZE] = {0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20,};
	FibonacciSearch(arrayC,20,9);

	cout << endl;
	int arrayD[MAXSIZE] = { 8,14,6,9,10,22,34,18,19,31,40,38,54,66,
									45,71,78,68,80,85,100,94,88,96,87 };
	int length = 25;
	blockSearch(arrayD,length,46);

	return 0;
}

然后是各函数所在源文件:

#include<iostream>
using namespace std;
#define MAXSIZE 30

struct Block {
	int valMin;
	int valMax;
	int index[10];
	int length;
};

void printArray(int array[],int length) {
	cout << "array : ";
	for (int i = 0; i < length; i++) {
		if (i % 10 == 0)
			cout << endl;
		printf("%4d",array[i]);
	}
	cout << endl;
}

void sequentialSearch(int array[], int length, int valForSearch) {
	printArray(array,length);

	if (array[0] == valForSearch) {
		cout << valForSearch << " 的位置是 : 1"<<endl;
		return;
	}
		
	array[0] = valForSearch;
	int i = length - 1;;
	while (array[i] != valForSearch)
		i--;
	if (i == 0)
		cout << valForSearch << "is not in this array !" << endl;
	else
		cout << valForSearch << " 的位置是 :" << (i + 1) << endl;
}

void binarySearch(int array[], int length, int valForSearch) {
	printArray(array,length);

	int start = 0, end = length - 1,mid;
	while (start <= end) {
		mid = (start + end) / 2;
		if (valForSearch < array[mid])
			end = mid - 1;
		else if (valForSearch > array[mid])
			start = mid + 1;
		else {
			cout << valForSearch << " 的位置是 :" << mid + 1 << endl;
			return;
		}
	}
	cout << valForSearch << " is not in this array !" << endl;
}

void interpolationSearch(int array[], int length, int valForSearch) {
	printArray(array, length);

	int start = 0, end = length - 1, mid;
	while (start <= end) {
		if (valForSearch < array[start])
			break;
		mid = start + (end - start) * (valForSearch - array[start])/(array[end] - array[start]);
		if (valForSearch < array[mid])
			end = mid - 1;
		else if (valForSearch > array[mid])
			start = mid + 1;
		else {
			cout << valForSearch << " 的位置是 :" << mid + 1 << endl;
			return;
		}
	}
	cout << valForSearch << " is not in this array !interpolation serch has bug!" << endl;
}

int Fibonacci(int index) {
	if (index == 0 || index == 1)
		return 1;
	else
		return Fibonacci(index - 1) + Fibonacci(index - 2);
}

void FibonacciSearch(int array[], int length, int valForSearch) {
	printArray(array,length);

	int fiboindex;
	for (fiboindex = 0; Fibonacci(fiboindex) < length; fiboindex++);
	for (int i = length; i < Fibonacci(fiboindex); i++)
		array[i] = array[length - 1];

	printArray(array,Fibonacci(fiboindex));


	int start = 0, end = Fibonacci(fiboindex) - 1,mid;
	while (start <= end) {
		if (fiboindex <=  2 && valForSearch > array[start] && valForSearch < array[end])
			break;
		mid = start + Fibonacci(fiboindex - 1) - 1;
		if (valForSearch < array[mid]) {
			end = mid;
			fiboindex--;
		}
		else if (valForSearch > array[mid]) {
			start = mid;
			fiboindex = fiboindex - 2;
		}
		else {
			cout << valForSearch << " 的位置在 :" << mid + 1 << endl;
			return;
		}
	}

	cout << valForSearch << " is not in array !" << endl;
}

void blockSearch(int array[], int length, int valForSearch) {
	
	Block blocks[5];
	blocks[0].length = 0; blocks[0].valMin = 0;  blocks[0].valMax = 20;
	blocks[1].length = 0; blocks[1].valMin = 21; blocks[1].valMax = 40;
	blocks[2].length = 0; blocks[2].valMin = 41; blocks[2].valMax = 60;
	blocks[3].length = 0; blocks[3].valMin = 61; blocks[3].valMax = 80;
	blocks[4].length = 0; blocks[4].valMin = 81; blocks[4].valMax = 100;

	for(int i = 0; i < length; i++) {
		int j;
		for (j = 0; j < 5; j++)
			if (array[i] >= blocks[j].valMin && array[i] <= blocks[j].valMax)
				break;
		blocks[j].index[blocks[j].length] = i;
		blocks[j].length++;
	}

	printArray(array,length);

	int start = 0, end = 4, mid;
	while (start <= end) {
		mid = (start + end) / 2;
		if (valForSearch > blocks[mid].valMax)
			start = mid + 1;
		else if (valForSearch < blocks[mid].valMin)
			end = mid - 1;
		else {
			for (int i = 0; i < blocks[mid].length; i++)
				if (valForSearch == array[blocks[mid].index[i]]) {
					cout << valForSearch << " 的位置在 :" << blocks[mid].index[i] + 1 << endl;
					return;
				}
			break;
		}
	}
	cout << valForSearch << " is not in the array !" << endl;
}

测试结果如下:
在这里插入图片描述
之所以举例里都找不到,是因为对找到的情况测试过了。
谢谢阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值