查找与排序
1、二分法查找
对一个序列使用二分法查找的话前提是这个序列是有序的,下面是二分法查找的实现:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int HalfFindValue(int ary[], const int& value, int low, int high)
{
if (low > high) //未找到
return -1;
int mid = (low + high) / 2;
if (ary[mid] == value)
return mid;
else if (value < ary[mid])
return HalfFindValue(ary, value, low, mid - 1);
else
return HalfFindValue(ary, value, mid + 1, high);
}
现有一个升序排列的数组,请找出绝对值最小的那个元素的位置。这道题可以借助二分法查找思想:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int HalfFindAbsMin(int ary[], int low, int high)
{
int mid = (low + high) / 2;
if (ary[mid] < 0) //如果ary[mid]小于0的话,往右找第一个大于或等于0的数
{
if (ary[mid + 1] < 0) //右边第一个数也小于0则递归查找
{
return HalfFindAbsMin(ary, mid + 1, high);
}
else //右边第一个数大于或等于0则最小的数即在本数和右边这个数之间产生
{
if (abs(ary[mid]) < ary[mid + 1])
return mid;
else
return mid + 1;
}
}
else if (ary[mid] > 0) //如果ary[mid]大于0的话,往左找第一个小于或等于0的数
{
if (ary[mid - 1] > 0) //左边第一个数也大于0则递归查找
{
return HalfFindAbsMin(ary, low, mid - 1);
}
else //左边第一个数小于等于0则最小的数即在本数和左边这个数之间产生
{
if (ary[mid] < abs(ary[mid - 1]))
return mid;
else
return mid - 1;
}
}
else //如果ary[mid]等于0的话0即为最小
{
return mid;
}
}
int MinAbs(int ary[], int n)
{
if (ary[0] >= 0) //全部元素都大于或等于0,第一个肯定是最小的
return 0;
if (ary[n - 1] <= 0) //全部元素都小于或等于0,最后一个的绝对值肯定是最小的
return n - 1;
return HalfFindAbsMin(ary, 0, n - 1); //数组中有负数也有正数
}
2、冒泡法排序
实现方法:将n个数两两比较取得最大的与最后一个元素互换,将n-1个数两两比较取得最大的与倒数第二个元素互换...,将2个数比较取得最大的与第2个元素互换。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void BubbleSort(int ary[], int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (ary[j] > ary[j + 1])
{
int temp = ary[j];
ary[j] = ary[j + 1];
ary[j + 1] = temp;
}
}
}
}
3、选择法排序
实现方法:从n个数里边选出最小的与第一个元素互换,从n-1个数里选出最小的与第二个元素互换...,从2个数里选出最小的与倒数第2个元素互换。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void SelectSort(int ary[], int n)
{
for (int i = 0; i < n - 1; i++)
{
int idx = i;
for (int j = i + 1; j < n; j++)
{
if (ary[j] < ary[idx])
idx = j;
}
if (idx != i)
{
int temp = ary[i];
ary[i] = ary[idx];
ary[idx] = temp;
}
}
}
4、插入排序
插入排序的实现方法是从第二个数开始依次与前面的数比较,如果比前面的数小的话就将前面的数后移一个单位。如以下的数组ary有5个元素:
3, 2, 1, 0, -1
ary[1]与前面的数依次比较(前面只有1个元素,可以认为是有序排列的),如果前面的数比ary[1]大的话就将前面的数后移一个单位,否则将ary[1]插入到合适位置,数组排列如下:
2, 3, 1, 0, -1
ary[2]与前面的数依次比较(前面两个元素是有序排列的),如果前面的数比ary[2]大的话就将前面的数后移一个单位,否则将ary[2]插入到合适位置,数组排列如下:
1, 2, 3, 0, -1
ary[3]与前面的数依次比较(前面三个元素是有序排列的),如果前面的数比ary[3]大的话就将前面的数后移一个单位,否则将ary[3]插入到合适位置,数组排列如下:
0, 1, 2, 3, -1
ary[4]与前面的数依次比较(前面四个元素是有序排列的),如果前面的数比ary[4]大的话就将前面的数后移一个单位,否则将ary[4]插入到合适位置,数组排序完成:
-1, 0, 1, 2, 3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void InsertionSort(int ary[], int n)
{
for (int i = 1; i < n; i++)
{
int temp = ary[i];
int j = i;
for (; j > 0; j--)
{
if (ary[j - 1] > temp)
ary[j] = ary[j - 1];
else
break;
}
ary[j] = temp;
}
}
5、快速排序
实现方法:从数组中取出一个数来,将数组中比这个数小的都放到其左边,自然的,这个数右边都是比它大的数,这个数在排序中的位置就定下了。然后用相同的方法对这个数的左边和右边的元素进行操作,显然快速排序适合用递归来实现。