二分查找
二分查找我们又叫它为折半查找法,二分查找的条件是查找对象必须是顺序表,并且表必须有序,我们以数组为例,模拟一下查找的过程:
假设这是我们要查找的数组,查找的数据为78
我们需要三个标志left,right,mid分别记录数组的左端,右端,和中间位置,然后我们将要查找的数据与mid(mid为lefi与right的中间位置)所指向的数据进行比较,会出现三种情况,如果查找数据大于mid所指数据,则表示查找数据的位置在mid的右边,这时候我们把left置为mid+1;如果查找数据小于mid所指数据,则表示查找数据的位置在mid的左边,这时候我们把right置为mid-1,然后继续之前的查找的方法,如果mid所指数据与查找数据相等,则返回mid 的值。
查找过程参照下图;
左边的查找方法也是一样的。
代码我们可以写成递归和循环两种,可以参照下面的代码 :
循环查找:
int FindValue(int val, int *ar,int right)
{
int left = 0;
int mid;
while (left <= right)
{
mid = (right - left) / 2 + left;
if (val<ar[mid])
{
right = mid - 1;
}
else if (val>ar[mid])
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
递归查找:
int FindValue1(int *ar,int val, int left,int right)
{
int mid = (right - left) / 2 + left;
if (val == ar[mid])
{
return mid;
}
else if (val>ar[mid])
{
return FindValue1(ar, val, mid + 1, right);
}
else if (val<ar[mid])
{
return FindValue1(ar, val, left, mid - 1);
}
return -1;
}
二分排序
二分排序是建立在二分查找之上的,原理我们可以这样理解,将要排序的数组分为两部分,对于第i(i从第二个数据开始)个数据,它的左边是有序的,右边是乱序,然后将第i的数据当成要查找的值,在左边中找到合适的位置插入,直到最后一位,排序完成,下面我们来模拟一下排序过程:
红线上的数值是下一趟的目标数值,我们可以发现他的左边都是有序的。
//二分排序
void sort(int *ar, int length)
{
int left, right, mid, temp;
for (int i = 1; i < length; i++)
{
temp = ar[i];
left = 0;
right = i - 1;
while (left <=right)
{
mid = (left + right) / 2;
if (ar[mid] < temp)
left = mid + 1;
else if (ar[mid]>temp)
right = mid - 1;
}
//找到合适位置后,所有的数值往后挪动一位,将目标值放在合适的位置
for (int k = i - 1; k>right; k--) {
ar[k + 1] = ar[k];
}
ar[right+1] = temp;//right指向目标值的左边一位,所以以要加一
}
for (int i = 0; i < length; i++)
{
cout << ar[i] << " ";
}
cout << endl;
}