【从零学习经典算法系列】分治策略实例——二分查找
2014-07-27 20:52
465 查看
1、二分查找算法简介
二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组
为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn)。
二分查找的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,二分查找方法适用于不经常变动而查找频繁的有序列表。
2、二分查找算法要求
(1)必须采用顺序存储结构
(2)必须按关键字大小有序排列。
3、二分查找算法流程图
![](http://img.blog.csdn.net/20140727201106337?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSmFzb25EaW5nMTM1NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1 二分查找算法流程图
4、c语言实现
![](http://img.blog.csdn.net/20140727205311030?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSmFzb25EaW5nMTM1NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图2 程序结果
5、造成边界错误的原因
二分查找算法的边界一般分为两种情况,一种为左闭右开区间,如[low,high),一种是左闭右闭区间,如[low,high]。这里需要注意的是循环体外的初始化条件,与循环体内的迭代步骤,都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此。
转载请注明作者与文章出处:/article/1490820.html
二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组
为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn)。
二分查找的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,二分查找方法适用于不经常变动而查找频繁的有序列表。
2、二分查找算法要求
(1)必须采用顺序存储结构
(2)必须按关键字大小有序排列。
3、二分查找算法流程图
图1 二分查找算法流程图
4、c语言实现
#include <stdio.h> int binary_search_recursion(const int array[], int low, int high, int key) { int mid = low + (high - low)/2; if(low > high) return -1; else{ if(array[mid] == key) return mid; else if(array[mid] > key) return binary_search_recursion(array, low, mid-1, key); else return binary_search_recursion(array, mid+1, high, key); } } int binary_search_loop(const int array[], int len, int key) { int low = 0; int high = len - 1; int mid; while(low <= high){ mid = (low+high) / 2; if(array[mid] == key) return mid; else if(array[mid] > key) high = mid - 1; else low = mid + 1; } return -1; } int main() { const int num_array[] = {2,4,6,8,10,12,14,16,18,20}; int key; int key_pos; int array_size = sizeof(num_array)/sizeof(int); for(int i=0;i<array_size;i++){ if(i % 5 == 0) printf("\n"); printf("%d ",num_array[i]); } printf("\n"); while(1){ printf("Put in the number you want to find:\n"); scanf("%d",&key); //key_pos = binary_search_recursion(num_array, 0, array_size, key); key_pos = binary_search_loop(num_array, array_size, key); printf("The position of key is %d\n", key_pos); } }
图2 程序结果
5、造成边界错误的原因
二分查找算法的边界一般分为两种情况,一种为左闭右开区间,如[low,high),一种是左闭右闭区间,如[low,high]。这里需要注意的是循环体外的初始化条件,与循环体内的迭代步骤,都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此。
int binary_search(int array[], int len, int key) { int left = 0; int right = len; //这里是int right = len,这里相当于[left,right)的形式,那么下面有两处地方需要修改,以保证一一对应: //1、下面循环的条件则是while(left < right) //2、循环内当array[middle]>value 的时候,right = middle while (left < right) { int middle=left + ((right-left)>>1); //防止溢出,移位也更高效。同时,每次循环都需要更新。 if (array[middle] > key) { right = middle; //right赋值,适时而变 } else if(array[middle] < key) { left = middle+1; } else return middle; } return -1; }
转载请注明作者与文章出处:/article/1490820.html
相关文章推荐
- 【从零学习经典算法系列】分治策略实例——归并排序(Mergesort)
- 【从零学习经典算法系列】分治策略实例——高速排序(QuickSort)
- 【从零学习经典算法系列】分治策略实例——快速排序(QuickSort)
- 二分查找算法的实现-分治策略
- 算法系列——五大经典查找1
- 算法学习---对象类型的数组二分查找实现
- 算法学习---基本数据类型的数组二分查找实现
- 算法系列15天速成——第六天 五大经典查找【下】
- 学习算法手记【原】- 二分查找
- 算法学习---对象类型的数组二分查找实现
- 算法系列15天速成——第四天 五大经典查找【上】
- 算法系列15天速成——第五天 五大经典查找【中】
- 经典算法:二分查找、插入排序、选择排序、冒泡排序
- MIT:算法导论——3.分治法实例_二分查找 和求a^b
- 每天学习一算法系列(14) (输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字)
- 算法系列15天速成——第六天 五大经典查找【下】
- 算法系列15天速成——第五天 五大经典查找【中】
- 算法系列15天速成 第五天 五大经典查找【中】
- 算法系列——五大经典查找2
- 经典算法:二分查找、插入排序、选择排序、冒泡排序