关于折半查找的细节思考
2016-10-24 16:12
267 查看
对于有序顺序表的查找我们知道最常用的是折半或者叫二分查找的策略。代码非常简洁,先看一眼:
看着非常符合自然的思维过程,只是不知道会不会问一个问题:为什么high = mid - 1, low = mid + 1呢?是不是可以high = mid, low = mid呢?是不是更简洁?
答案是不可以的。
如果这么写了,将无法查找最后一个元素。当最后只剩3个元素时,mid可以取到中间那个数,这样low,high指向的数相邻。再次计算mid时,再也不能跳到high的值,因为我们知道计算机里的除有下取整的效果。所以,无法索引到最后一个数值。中间的都是可以的,而且第一个也可以。为什么呢?假设查找第一个数,最后low指向第一个,high指向第二个,下一次计算mid,恰好可以得到第一个数的位置。因此,可以查到。
看到这里,似乎可以想到,只需要low = mid + 1,则high两种方式都可以了,即high = mid,或者high = mid都行。
对的,确实是这样。分析的方法一样。关键在于看到low要有前进一步计算,这样才能达到最高位置的数。高位的就随便它好了。但是还是推荐high = mid - 1, low = mid + 1的写法。
完整测试代码,想实际验证的,编译运行测试即可。
int BinarySearch(vector<int> ins, int key) { int low = 0,high = ins.size() - 1, mid; while(low <= high) { mid = (low + high) / 2; if(ins[mid] == key) { return mid; } else if(ins[mid] > key) { high = mid - 1; } else { low = mid + 1; } } return -1; }
看着非常符合自然的思维过程,只是不知道会不会问一个问题:为什么high = mid - 1, low = mid + 1呢?是不是可以high = mid, low = mid呢?是不是更简洁?
答案是不可以的。
如果这么写了,将无法查找最后一个元素。当最后只剩3个元素时,mid可以取到中间那个数,这样low,high指向的数相邻。再次计算mid时,再也不能跳到high的值,因为我们知道计算机里的除有下取整的效果。所以,无法索引到最后一个数值。中间的都是可以的,而且第一个也可以。为什么呢?假设查找第一个数,最后low指向第一个,high指向第二个,下一次计算mid,恰好可以得到第一个数的位置。因此,可以查到。
看到这里,似乎可以想到,只需要low = mid + 1,则high两种方式都可以了,即high = mid,或者high = mid都行。
对的,确实是这样。分析的方法一样。关键在于看到low要有前进一步计算,这样才能达到最高位置的数。高位的就随便它好了。但是还是推荐high = mid - 1, low = mid + 1的写法。
完整测试代码,想实际验证的,编译运行测试即可。
#include <iostream> #include <vector> using namespace std; int BinarySearch(vector<int> ins, int key) { int low = 0,high = ins.size() - 1, mid; while(low <= high) { mid = (low + high) / 2; if(ins[mid] == key) { return mid; } else if(ins[mid] > key) { high = mid - 1; } else { low = mid + 1; } } return -1; } int main() { vector<int> ins; int n; cin >> n; for(int i = 0; i < n; i++) { int a; cin >> a; ins.push_back(a); } int key; cin >> key; cout << BinarySearch(ins,key) << endl; }
相关文章推荐
- 关于指令执行周期的细节思考
- 【react学习】关于react框架使用的一些细节要点的思考
- (转)关于玩法创新和细节优化的思考——想盖房缺砖
- 【react学习】关于react框架使用的一些细节要点的思考
- 【react】关于react框架使用的一些细节要点的思考
- 关于C函数memcpy的实现细节思考
- 【react】关于react框架使用的一些细节要点的思考
- 关于我们的思考——“项目开发”及读《人月神话》有感
- 关于软件注册的一点思考
- 关于.Text如何过滤恶意脚本的思考
- 关于中国软件业国际化的思考
- 关于Java继承一个值得思考的问题。
- 关于人生哲理——思考
- 关于Windows下ShellCode编写的一点思考
- 关于异常的再思考
- 关于系统思考——现代科学抑郁症
- 关于blog的思考。
- 关于refactoring思考(七)
- 关于软件的思考(2002.08.13)
- 关于Matrix黑客帝国的进一步思考(转贴)