这学期刚刚接触c++,碰到了不少问题,也碰到了许多解决问题非常好的方法,下面就介绍一下复习中再次碰到的“折半查找法”。
折半查找法,以我自己的理解即为:用目标元素与有序数列的中间值进行比较,通过不断缩小搜索的范围,来确定目标元素是否在数列中或在数列什么位置。若中值与目标元素相等,则操作结束,目的达成;若小于中值(假设已知有序数列从小到大排列【要注意原数列的排列方式】),则取左半部分重复之前操作;若大于中值,则取右半部分重复之前操作。
这种算法对于处理大量数据的时候有显著的优点,可以通过扔去无用数据来缩减许多时间。
下面以此题为例:
有15个数按由小到大的顺序放在一个数组中,输入一个数,判断该数是数组中的第几个元素的值。如果该数不在数组中,则打印“ 无此数 ”。
以下我使用了两种方法
1.常规方法
#include <iostream>
using namespace std;
int main()
{
int a[15]={20,19,18,17,16,14,12,10,9,8,6,5,3,2,1};
//(随便的15个由大到小的数)
int b;
cout<<"输入要查找的数:";
cin>>b;
int L=0,R=14;
//定义两个新的整型变量:分别存放第一个数组元素的序号和最后一个数组元素的序号
int Z;
while(L<=R)
{
Z=(L+R)/2; //Z即为此时数组中间元素的序号
if(b==a[Z])
break;
else if(b>a[Z]) //注意数列是从大到小
{
R=Z-1;
}
else if(b<a[Z])
{
L=Z+1;
}
}
if(b==a[Z]) //判断数是否存在于数组中
cout<<"目标元素是数组第"<<Z+1<<"个元素的值";
else
cout<<"无此数";
return 0;
}
2.递归法
#include <iostream>
using namespace std;
int main()
{
int a[15] = { 20,19,18,17,16,14,12,10,9,8,6,5,3,2,1 };
int b;
cout << "输入要查找的数:";
cin >> b;
int ZheBan(int a[],int left,int right,int key);
//声明函数
if(ZheBan(a,0,14,b)==-1)
cout<<"无此数";
else
cout<<<"目标元素是数组第"<<ZheBan(a,0,14,b)+1<<"个元素的值";
/* if (b == a[ZheBan(a, 0, 14, b)])
cout << "目标元素是数组第" << ZheBan(a, 0, 14, b) + 1 << "个元素的值";
else
cout << "无此数"; */
//上面的这串代码我编写的时候也可以正常对目标元素状态进行判断,但是不很规范
return 0;
}
int ZheBan(int a[],int left,int right,int key)
{
int l=left,r=right,z=(left+right)/2;
if(key==a[z])
return z;
if (l > r) //可以理解为若目标元素不存在的递归循环结束条件
return -1;
if(key>a[z])
return ZheBan(a,l,r-1,key);
if(key<a[z])
return ZheBan(a,l+1,r,key);
return -1;
}
花了很长时间思考整理,感觉很有意义,希望也可以帮助到需要的人^_^