1. 程式人生 > >二分查詢與二分排序

二分查詢與二分排序

二分查詢

二分查詢我們又叫它為折半查詢法,二分查詢的條件是查詢物件必須是順序表,並且表必須有序,我們以陣列為例,模擬一下查詢的過程:

假設這是我們要查詢的陣列,查詢的資料為78

我們需要三個標誌left,right,mid分別記錄陣列的左端,右端,和中間位置,然後我們將要查詢的資料與mid(mid為lefi與right的中間位置)所指向的資料進行比較,會出現三種情況,如果查詢資料大於mid所指資料,則表示查詢資料的位置在mid的右邊,這時候我們把left置為mid+1;如果查詢資料小於mid所指資料,則表示查詢資料的位置在mid的左邊,這時候我們把right置為mid-1,然後繼續之前的查詢的方法,如果mid所指資料與查詢資料相等,則返回mid 的值。

查詢過程參照下圖;

左邊的查詢方法也是一樣的。

程式碼我們可以寫成遞迴和迴圈兩種,可以參照下面的程式碼 :

迴圈查詢:

int FindValue(int val, int *ar,int right)
{
	int left = 0;
	int mid;
	while (left <= right)
	{
		mid = (right - left) / 2 + left;
		if (val<ar[mid])
		{
			right = mid - 1;
		}
		else if (val>ar[mid])
		{
			left = mid + 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;
}

遞迴查詢:

int FindValue1(int *ar,int val, int left,int right)
{
	int mid = (right - left) / 2 + left;
	if (val == ar[mid])
	{
		return mid;
	}
	else if (val>ar[mid])
	{
		return FindValue1(ar, val, mid + 1, right);
	}
	else if (val<ar[mid])
	{
		return FindValue1(ar, val, left, mid - 1);
	}
	return -1;

	}

 二分排序

二分排序是建立在二分查詢之上的,原理我們可以這樣理解,將要排序的陣列分為兩部分,對於第i(i從第二個資料開始)個數據,它的左邊是有序的,右邊是亂序,然後將第i的資料當成要查詢的值,在左邊中找到合適的位置插入,直到最後一位,排序完成,下面我們來模擬一下排序過程:

紅線上的數值是下一趟的目標數值,我們可以發現他的左邊都是有序的。 

//二分排序
void sort(int *ar, int length)
{
	int left, right, mid, temp;
	for (int i = 1; i < length; i++)
	{
		temp = ar[i];
		left = 0;
		right = i - 1;
		while (left <=right)
		{
		    mid = (left + right) / 2;
			if (ar[mid] < temp)
				left = mid + 1;
			else if (ar[mid]>temp)
				right = mid - 1;
		}
        //找到合適位置後,所有的數值往後挪動一位,將目標值放在合適的位置
		for (int k = i - 1; k>right; k--)		{
			ar[k + 1] = ar[k];
		}
		ar[right+1] = temp;//right指向目標值的左邊一位,所以以要加一
	}
	for (int i = 0; i < length; i++)
	{
		cout << ar[i] << " ";
	}
	cout << endl;
}