您的位置:首页 > 其它

二分(折半)查找

2013-11-18 21:22 288 查看
折半查找:又叫二分查找,采用分治思想,适用于不经常变动且查找频繁的表;

算法思想:

将n个元素(假设n个元素升序)分为大致相同的两部分,取data[n / 2] 与目标元素m比较:

若data[n/2] == m:return (n / 2);

若data[n/2] > m:则我们只要在data[]的左半部分继续查找;

若data[n/2] < m:则我们只要在data[]的有半部分继续查找;

时间复杂度:O(logn)

优点:比较次数少,查找速度快,平均性能好;

缺点:要求待查表为"有序表",且插入删除困难;

边界错误问题:

(1)左闭右开区间([left , right))。

left = 0 , right = length;

循环条件while(left < right):

data[middle] > m:right = middle;

data[middle] < m: left = middle + 1;

(2)左右皆闭区间([left , right])。

left = 0 , right = length - 1;

循环条件while(left <= right):

data[middle] > m:right = middle - 1;

data[middle] < m:left = middle + 1;

循环体外的初始化条件与循环体内的初始化条件,在迭代时必须一致的区间规则;

代码实现:

#include<iostream>
#include<exception>
using  namespace std;
//---------------------------------------------二分查找(顺序查找)---------------------------------------
int BinSearch_Soulation1(const int* data , int length , int m)
{
//左闭右闭区间
int left = 0;
int right = length - 1 ;

while(left <= right)
{
//middle = (right + left) / 2 不可取;
//若(right + left) 溢出时,出现错误;
int middle = left + (right - left) / 2;

if(data[middle] > m)
{
right = middle - 1;
}
else if(data[middle] < m)
{
left = middle + 1;
}
else
{
return middle;
}
}

return -1;
}

int BinSearch_Soulation2(const int* data , int length , int m)
{
//左闭右开区间
int left = 0;
int right = length;
int middle;

while(left < right)
{
middle = left + ((right - left) / 2);

if(data[middle] > m)
{
right = middle;
}
else if(data[middle] < m)
{
left = middle + 1;
}
else
{
return middle;
}
}

return -1;
}

int BinSearch_Soulation3(const int* data, int length, int m)
{
int left, right, middle;

left = -1, right = length;

while (left + 1 != right)//这个循环维持的条件是left<right && array[left]<v<=array[right],所以到最后的时候,
{//如果可以找到目标,则只剩下两个数,并且满足 array[left]<v<=array[right],是要查找的数是right
middle = left + (right - left) / 2;

if (data[middle] < m)//必须保证array[left]<v<=array[right],所以left = middle;
{//如果left =middle+1,则有可能出现 array[left]<=v的情况
left = middle;
}
else
{
right = middle;
}
}

if (right >= length || data[right] != m)
{
right = -1;
}

return right;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: