问题描述:
给定已按升序排好的n个元素a[0:n-1],现要在这n个元素中找出一特定元素x。
问题分析:
采用分治法的思想,充分利用元素之间已存在的次序关系,将排好序的数组a[0:n-1]划分成两个个数相同的左、右两部分,取[n/2]与x进行比较,如果x=a[n/2],则找到x,算法结束;
如果x>a[n/2],则在数组a划分得到的右半部分继续查找;
如果x<a[n/2],则在数组a划分得到的左半部分继续查找;
在数组a左半部或右半部分继续查找x的过程采用同样的分治法。
按照上述的思想,折半查找的代码如下:
第一种:非递归处理
#include<iostream>
using namespace std;
//非递归处理
int TSearch(int* arr, int key,int low, int high)
{
while (low <= high)
{
int mid = (low + high) / 2;
if (key == arr[mid])
{
//对于第0位以及重复项的判断
if (mid == 0 || arr[mid - 1] != key)
return mid;
else
high = mid - 1;
}
else if (key > arr[mid])
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main()
{
//按照升序,故两个相同的数肯定在一块
int arr[] = { 1,1,4,6,8,8,9,13,16,27,32 };
int len = sizeof(arr) / sizeof(arr[0]);
cout << "请输入你要查询的数:";
int n;
cin >> n;
int location = TSearch(arr, n, 0, len - 1);
if (location == -1)
cout << "没有找到这个数!" << endl;
else
cout << "这个数在" << location << "号位置" << endl;
return 0;
}
第二种:递归处理
#include<iostream>
using namespace std;
//递归处理
int TSearch(int* arr, int key,int low,int high)
{
if (low > high)
return -1;
int mid = (low + high) / 2;
if (key == arr[mid])
{
//对于第0位以及重复项的判断
if (mid == 0 || arr[mid - 1] != key)
return mid;
else
return TSearch(arr, key, low, mid - 1);
}
else if (key > arr[mid])
TSearch(arr, key, mid + 1, high);
else
TSearch(arr, key, low, mid-1);
}
int main()
{
//按照升序,故两个相同的数肯定在一块
int arr[] = { 1,1,4,6,8,8,9,13,16,27,32 };
int len = sizeof(arr) / sizeof(arr[0]);
cout << "请输入你要查询的数:";
int n;
cin >> n;
int location = TSearch(arr, n, 0, len - 1);
if (location == -1)
cout << "没有找到这个数!" << endl;
else
cout << "这个数在" << location << "号位置" << endl;
return 0;
}