折半查找:就是对一组有序的数据(必须是有序,然后递增的,不过也可以是递减的,不过得稍微修改下代码),每次取序列中间的数与关键字比较,如果关键字小于中间的数,则关键字不可能落在大于中间到最右边的那一段序列里,所以下一次就只需要在中间数的左边的序列里查找,如果关键字大于中间的数,类似于小于中间的数,下一次查找只需要查找右边序列。
(0)初始化:
left = 0;
right = n;
middle = (left+righ)/2;
[R0..............................Rm.............................Rn]
↑ ↑ ↑
left middle right
(1)如果 关键字key < data[middle]:
left = left;
right = middle-1;
middle = (left+righ)/2;
[R0.........Rm..........Rn]
↑ ↑ ↑
left middle right
(2)如果 关键字key > data[middle]:
left = middle+1;
right = right;
middle = (left+righ)/2;
[R0...........Rm.........Rn]
↑ ↑ ↑
left middle right
(3)如果 关键字key == data[middle],就找到咯。
(4)不断重复 (1) (2) (3)。
#include <iostream>
using namespace std;
// 折半查找
// 必须保证数据要是"有序"和"递增"的
int binarySearch(int data[], int n, int key)
{
int left = 0;
int right = n;
int middle;
while (left <= right)
{
middle = (left + right)/2;
// 关键字key小于中间的元素
if (key < data[middle])
{
left = middle + 1;
}
// 相等
else if (key == data[middle])
{
return middle;
}
// 关键字key大于中间的元素
else
{
right = middle - 1;
}
}
return -1;
}
int main()
{
int data[10] = {0,1,2,3,4,5,6,7,8,9};
int n = 9;
int index = binarySearch(data, n, 4);
cout<<index<<endl;
if (index!=-1)
{
cout<<data[index];
}
return 0;
}
其实,折半查找就是一棵二叉树,把第一个中间点看成根结点,中间点左边的序列就是左子树,中间结点右边的序列就是右子树,依次类推,根据二叉树的性质,有n个结点的二叉树的深度为k=logn+1(注意logn的底为2)所以,折半查找最坏也是O(logn).