二分查詢與二分排序
阿新 • • 發佈:2019-01-08
二分查詢
二分查詢我們又叫它為折半查詢法,二分查詢的條件是查詢物件必須是順序表,並且表必須有序,我們以陣列為例,模擬一下查詢的過程:
假設這是我們要查詢的陣列,查詢的資料為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;
}