二分法查詢資料(遞迴)
阿新 • • 發佈:2018-12-22
二分查詢
二分法又稱折半查詢,即每次取中間記錄查詢的方法。二分法查詢的前提是線性表中
的記錄必須是關鍵碼有序(通常從小到大有序),線性表必須採用順序儲存。
遞迴
遞迴就是在執行中呼叫自己(C++不允許main()呼叫自己)。 條件:1、子問題必須與原始問題為同樣的事,且更為簡單; 2、不能無限制地呼叫本身,須有個出口,化簡為非遞迴狀況處理。 缺點:執行效率低。在遞迴呼叫過程中系統為每一層的返回點、區域性量等開闢了棧來 儲存,遞迴次數過多容易造成棧溢位等。 型別:1、包含一個遞迴呼叫的遞迴 2、包括多個遞迴呼叫的遞迴 在需要將一項工作不斷分成兩項較小的、類似的工作時,遞迴非常有用。
//二分法查詢資料 int Binary_Search(int *a,int low, int high, int key) { int mid = low + ((high - low) >> 1);//避免溢位 if (key == a[mid]) return mid; while (low <= high) { if (key < a[mid]) { high = mid - 1; return Binary_Search(a, low, high, key); } else if (key > a[mid]) { low = mid + 1; return Binary_Search(a, low, high, key); } else return mid; } return -1;//返回異常 }
二分法查詢資料關鍵是記錄中間值,將資料分成前半段和後半段,每次將
需要查詢的值與中間值進行比較,若小於中間值,則查詢前半段,將mid-1
賦給當前要查詢的最後一個數據,大於則查詢後半段,將mid+1賦給當前
要查詢的第一個資料,若等於中間值,則輸出mid,跳出迴圈。
//查詢第一個等於給定值的元素 int Binary_Search_First(int *b, int low, int high, int key) { int mid = low + ((high - low) >> 1); while (low <= high) { if (key < b[mid]) { high = mid - 1; return Binary_Search_First(b, low, high, key); } else if (key > b[mid]) { low = mid + 1; return Binary_Search_First(b, low, high, key); } else if ((b[mid - 1]!= key)||(low==mid)) return mid; else { high = mid - 1; return Binary_Search_First(b, low, high, key); } } return -1; }
該問題為有序可重複陣列資料查詢問題,與上述有序無重複陣列查詢問題
類似,但是當要查詢的資料與中間值相等時分為兩種情況,一種是中間值
前面的資料不為要查詢的資料,另一種是中間值前面的資料等於要查詢的
資料,此時仍需對前半段進行資料查詢。
//查詢最後一個等於給定值的元素
int Binary_Search_Last(int *b, int low, int high, int key)
{
int mid = low + ((high - low) >> 1);
while (low <= high)
{
if (key < b[mid])
{
high = mid - 1;
return Binary_Search_Last(b, low, high, key);
}
else if (key > b[mid])
{
low = mid + 1;
return Binary_Search_Last(b, low, high, key);
}
else if ((b[mid + 1] != key) || (high == mid))
return mid;
else
{
low = mid + 1;
return Binary_Search_Last(b, low, high, key);
}
}
return -1;
}
此問題與上述問題類似,只是當中間值與給定值相等時需要對中間值的
下一個資料進行判斷,方法雷同。