一点一滴成长

导航

查找与排序

1、二分法查找

  对一个序列使用二分法查找的话前提是这个序列是有序的,下面是二分法查找的实现:

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);
}
View Code

  现有一个升序排列的数组,请找出绝对值最小的那个元素的位置。这道题可以借助二分法查找思想:

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); //数组中有负数也有正数
}
View Code

2、冒泡法排序

  实现方法:将n个数两两比较取得最大的与最后一个元素互换,将n-1个数两两比较取得最大的与倒数第二个元素互换...,将2个数比较取得最大的与第2个元素互换。

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;
            }
        }
    }
}
View Code

3、选择法排序

  实现方法:从n个数里边选出最小的与第一个元素互换,从n-1个数里选出最小的与第二个元素互换...,从2个数里选出最小的与倒数第2个元素互换。

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;
        }
    }
}
View Code

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

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;
    }
}
View Code

5、快速排序

  实现方法:从数组中取出一个数来,将数组中比这个数小的都放到其左边,自然的,这个数右边都是比它大的数,这个数在排序中的位置就定下了。然后用相同的方法对这个数的左边和右边的元素进行操作,显然快速排序适合用递归来实现。

posted on 2018-04-25 13:47  整鬼专家  阅读(863)  评论(0编辑  收藏  举报