二分法:二分查找(递归+非递归)实现
生活随笔
收集整理的這篇文章主要介紹了
二分法:二分查找(递归+非递归)实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二分查找又稱折半查找,首先,假設表中元素是按升序排列,將 表中間位置的關鍵字與查找關鍵字比較:
- 如果兩者相等,則查找成功;
- 否則利用中間位置將表分成前、后兩個子表:
1)如果中間位置的關鍵字大于查找關鍵字,則進一步查找前一子表
2)否則進一步查找后一子表 重復以上過程,直到找到滿足條件的記錄,使查找成功,或直到子表不存在為止,此時查找不成功。
例如:target = 200
arr = [-1,2,5,20,90,100,320]
使用二分查找,從arr中查找target是否存在
- 取中間位置為20 ,20 < 200
- 縮小查找空間 [90,100,320],二分查找中間位置100 < 200
- 縮小查找空間[320,320],begin == end
- 未找到 200,返回失敗
問題描述如下:
已知一個排序數組A,如 A = [-1, 2, 5, 20, 90, 100, 207, 800], 另外一個亂序數組B,如 B = [50, 90, 3, -1, 207, 80], 求B中的任意某個元素,是否在A中出現,結果存儲在數組C中,出現 用1代表,未出現用0代表,如,C = [0, 1, 0, 1, 1, 0]。
以上過程如果使用暴力搜索,則需要O(n*m)即O(n^2);
這里使用二分查找則僅僅需要O(log2n)的時間復雜度:
n/2 + n/4 + … + n/2^k (k為循環的次數)
由于你n/2^k (取最壞的情況,最后一次僅剩下一個數)
即令n/2^k=1
可得k=log2n,(是以2為底,n的對數)
所以時間復雜度可以表示O(h)=O(log2n)
遞歸實現如下:
bool find_part(std::vector<int> arr, int begin, int end, int target) {if (begin > end) {//結束條件return false;}int mid = (begin + end) / 2;if (arr[mid] == target) {return true;} else if (arr[mid] > target) {return find_part(arr, begin, mid -1, target);} else {return find_part(arr, mid + 1, end, target);}
}std::vector<int> get_result(std::vector<int> arr, std::vector<int> target) {std::vector<int> v;for (int i = 0;i < target.size(); ++i) {int result = find_part(arr,0,arr.size() - 1, target[i]);v.push_back(result);}return v;
}
非遞歸實現:
std::vector<int> find_part_norecur(std::vector<int> arr1, std::vector<int> target) {std::vector<int> result;for (int i = 0;i < target.size(); ++i) {int begin = 0;int end = arr1.size();while(begin <= end) {int mid = (begin + end) / 2;if(arr1[mid] == target[i]) {result.push_back(1);break;} else if (arr1[mid] > target[i]) {end = mid - 1;} else {begin = mid + 1;}}if (begin >= end){result.push_back(0);}}return result;
}
測試代碼如下:
#include <iostream>
#include <vector>using namespace std;bool find_part(std::vector<int> arr, int begin, int end, int target) {if (begin > end) {return false;}int mid = (begin + end) / 2;if (arr[mid] == target) {return true;} else if (arr[mid] > target) {return find_part(arr, begin, mid -1, target);} else {return find_part(arr, mid + 1, end, target);}
}std::vector<int> get_result(std::vector<int> arr, std::vector<int> target) {std::vector<int> v;for (int i = 0;i < target.size(); ++i) {int result = find_part(arr,0,arr.size() - 1, target[i]);v.push_back(result);}return v;
}std::vector<int> find_part_norecur(std::vector<int> arr1, std::vector<int> target) {std::vector<int> result;for (int i = 0;i < target.size(); ++i) {int begin = 0;int end = arr1.size();while(begin <= end) {int mid = (begin + end) / 2;if(arr1[mid] == target[i]) {result.push_back(1);break;} else if (arr1[mid] > target[i]) {end = mid - 1;} else {begin = mid + 1;}}if (begin >= end){result.push_back(0);}}return result;
}int main(int argc, char const *argv[])
{std::vector<int> arr1;std::vector<int> target;int n;cin >> n;for (int i = 0;i < n; ++i) {int tmp;cin >> tmp;arr1.push_back(tmp);}int t;cin >> t;for (int i = 0;i < t; ++i) {int tmp;cin >> tmp;target.push_back(tmp);} std::vector<int> result;// result = get_result(arr1, target);result = find_part_norecur(arr1,target);for (int i = 0;i < result.size(); ++i) {cout << result[i] << " ";}return 0;
}
輸出如下:
#輸入序列數組
5
2 3 4 5 6
#輸入目標數組
3
1 3 5
#輸出
0 1 1
總結
以上是生活随笔為你收集整理的二分法:二分查找(递归+非递归)实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: t-top 命令详解
- 下一篇: 二分法:search insert po