查找——折半查找

###1、折半查找 折半查找(Binary Search)又稱爲二分查找。 注意 折半查找方法要求查找表的數據是線性結構保存,而且還要求查找表中的數據是按關鍵字由小到大有序排列。 ####折半查找的具體過程 假設有n個元素的查找表,首先計算位於查找表中間位置元素的序號m(m=n/2),取s[m]的關鍵字與給定值key進行比較。比較結果有3種可能 (1)若s[m]=key,表示查找成功。 (2)若s[m]>key,表示關鍵字key只可能在查找表的前半部分(因查找表中的數據是按從小到大的順序排 列),則在前半部分繼續進行折半查找。 (3)若s[m]<key,表示關鍵字key只可能在查找表的後半部分,則在後半部分繼續進行折半查找。 技巧 從上面的過程可看出,折半查找是一種遞歸過程。每折半查找一次,可以使查找範圍縮小一半,當查找範 圍縮小到只剩下一個元素,而該元素仍與關鍵字不相等,則說明查找失敗。 在最壞的狀況下,折半查找所需的比較次數爲O(nlog 2 n),其查找效率比順序查找法要快不少 例如,有如下數據: 6,12,28,37,54,65,69,83,90,92 若要查找關鍵字37,則查找過程以下圖1:數組

輸入圖片說明

從上圖1的查找過程可看出,經過4次比較,可找到關鍵字37所在的位置。再例如,若要查找關鍵字66,其查找過程以下圖2:測試

輸入圖片說明

從上圖2的過程可看出,經過4次比較,當查找範圍縮小到只剩一個元素,仍沒有找到指定關鍵字,說明查找失敗。code

###2、折半查找實現 ####折半查找法排序

/**
 *折半查找法(非遞歸)
 * */
int BinarySearch1(int s[], int n, int key)
{
	int low, high, mid;

	low = 0;
	high = n-1;
	while (low <= high) {		//查找結束條件,即至少包含一個元素
		mid = (low + high)/2;	//計算中間位置
		if (s[mid] == key)		//若是中間位置與關鍵字相同
			return mid;			//返回序號
		else if (s[mid] > key)	//中間元素大於關鍵字,關鍵字在左邊
			high = mid - 1;		//從新定義high
		else					//中間元素大於關鍵字,關鍵字在右邊
			low = mid + 1;		//從新定義low
	}
	return -1;
}

/**
 *折半查找法(遞歸)
 * */
int BinarySearch2(int s[], int low, int high, int key)
{
	int mid;

	if (low <= high) {			//查找結束條件,即至少包含一個元素
		mid = (low + high)/2;	//計算中間位置
		if (s[mid] == key)		//若是中間位置與關鍵字相同
			return mid;			//返回序號
		else if (s[mid] > key)	//中間元素大於關鍵字,關鍵字在左邊
			return BinarySearch2(s, low, mid-1, key);
		else
			return BinarySearch2(s, mid+1, high, key);
	} else
		return -1;
}

####折半查找法測試遞歸

#include <stdio.h>
#include "BinarySearch.c"

#define ARRAYLEN 10
int main()
{
	int key, i, pos;
	int source[ARRAYLEN]={6, 12, 28, 37, 54, 65, 69, 83, 90, 92};

	/*折半查找,非遞歸*/
	printf("請輸入查找關鍵字:");
	scanf("%d", &key);
	pos = BinarySearch1(source, ARRAYLEN, key);

	printf("原數據:");
	for (i=0; i< ARRAYLEN; i++)
		printf("%d ", source[i]);
	printf("\n");

	if (pos >= 0)
		printf("查找成功,關鍵字%d位於數組的第%d個位置\n", key, pos);
	else
		printf("查找失敗,關鍵字%d不在數組中\n", key);

	/*折半查找,遞歸*/
	printf("請輸入查找關鍵字:");
	scanf("%d", &key);
	pos = BinarySearch2(source, 0, ARRAYLEN-1, key);
	printf("原數據:");
	for (i=0; i< ARRAYLEN; i++)
		printf("%d ", source[i]);
	printf("\n");

	if (pos >= 0)
		printf("查找成功,關鍵字%d位於數組的第%d個位置\n", key, pos);
	else
		printf("查找失敗,關鍵字%d不在數組中\n", key);
}

###3、折半查找特色 ❑優勢:查找速度快,最多查找次數爲O(nlog 2 n)圖片

❑缺點:對查找表中的數據有順序要求,在進行查找前首先進行排序。若是須要將查找不成功的關鍵字數據添加到查找表中,則須要對查找表中的已有數據進行大量的移動操做。it

相關文章
相關標籤/搜索