一,可以使用二分查找的要求
- 線性表必須採用順序存儲結構
- 表中元素按關鍵字有序排列
二,查找的過程
- 從表的中間記錄開始,如果查找值與中間記錄的關鍵字相等,則查找成功;
- 如果查找值大於或小於中間記錄的關鍵字,則在表中大於或小於中間記錄的那一半中查找;
- 重複上面步驟,直到查找成功,或者表中無查找值,則返回錯誤。
三,算法步驟
- 定義新的low, high。並將low賦值爲0,high賦值爲表長
-
當low小於high時,循環執行下面操作
- mid取low和high的中間值,此時有三種方法:mid = (low+high)/2 mid=low+(high-low)/2 mid=low+((high-low)>>1)
- 將查找值n與中間位置關鍵字進行比較,相等則查找成功,跳出循環
- 不相等則利用中間位置,將表分爲兩部分。如果小於則high=mid-1;否則low=mid+1;
- 一直到循環結束,如果還未找到查找值,則顯示錯誤
四,一種代碼實現方法
#include<iostream>
using namespace std;
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int low = 0, high = 9;
cout << "想要找的值:";
int n;
cin >> n;
//採用循環方法
while (low <= high)
{
int mid = (low + high) / 2; //取中值
if (a[mid] == n) //找到
{
cout << mid;
break;
}
else if (a[mid] < n) //小於所求值
{
low = mid + 1;
}
else //大於所求值
{
high = mid - 1;
}
}
if (low>high) //線性表中無所求值,顯示錯誤
{
cout << "error";
}
system("pause");
return 0;
}
另一種實現方法
#include<iostream>
using namespace std;
void Find(int *a, int low, int high, int n)
{
if (low > high) //發生錯誤
{
cout << "error";
}
else
{
int mid = (low + high) / 2; //求中間值
if (a[mid] == n) //找到所求值
{
cout << mid;
}
else if (a[mid] < n) //兩種函數循環方法
{
Find(a, mid + 1, high, n);
}
else
{
Find(a, low, mid - 1, n);
}
}
}
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int low = 0, high = 9;
cout << "想要找的值:";
int n;
cin >> n;
Find(a, low, high, n); //將數據傳入函數中
system("pause");
return 0;
}
拓展
一,求第一個等於查找值的位置
此時判斷的重點就在於,當mid記錄的關鍵字與所求值相同時,還需要判斷mid前的值是否與所求值相同;
如果相同則說明當前mid還不是第一個等於所求值的,所以仍需將high賦值爲mid-1,繼續循環。
代碼
#include<iostream>
using namespace std;
int main()
{
int a[10] = { 1, 2, 3, 5, 5, 5, 5, 8, 9, 10 };
int low = 0, high = 9;
cout << "想要找的值:";
int n;
cin >> n;
//採用循環方法
while (low <= high)
{
int mid = (low + high) / 2; //取中值
if (a[mid] < n) //小於情況
{
low = mid + 1;
}
else if (a[mid] > n) //大於情況
{
high = mid - 1;
}
else //等於
{
if (a[mid - 1] != n || mid == 0) //等於且當前mid即爲第一個值
{
cout << mid;
break;
}
high = mid - 1; //否則繼續循環
}
}
if (low>high) //線性表中無所求值,顯示錯誤
{
cout << "error";
}
system("pause");
return 0;
}
二,查找最後一個小於所求值的位置
即爲上面的第一個等於查找值位置的前一個
代碼
#include<iostream>
using namespace std;
int main()
{
int a[10] = { 1, 2, 3, 5, 5, 5, 5, 8, 9, 10 };
int low = 0, high = 9;
cout << "想要找的值:";
int n;
cin >> n;
int mid;
//採用循環方法
while (low <= high)
{
mid = (low + high) / 2; //取中值
if (mid == 0)
{
break;
}
//cout << mid<<endl;
if (a[mid] < n) //小於情況
{
low = mid + 1;
}
else if (a[mid] > n) //大於情況
{
high = mid - 1;
}
else //等於
{
if (a[mid - 1] != n) //等於且當前mid即爲第一個等於所求值的值
{
cout << mid - 1; //則返回第一個值的前一個
break;
}
high = mid - 1; //否則繼續循環
}
}
if (low>high || mid ==0) //線性表中無所求值,顯示錯誤
{
cout << "error";
}
system("pause");
return 0;
}