【算法和数据结构】排序(四)归并排序和快速排序(C++实现)

前言:
      前面三篇文章分别介绍了三种排序算法:冒泡排序插入排序选择排序。它们的实现思想都是基于排序问题本身产生的,时间复杂度都是θ(n^2)。
       而现在介绍的两种排序算法:归并排序和快速排序,它们的思想除了对于排序本身外,还可以进一步抽象为:分治思想

一、分治思想
       分治思想,顾名思义就是将一个大而复杂的问题分解为若干个性质相同且相互独立 的小问题分别求解,然后找到合适的组合方法将若干小问题的解组合生成原问题的解。
       如果第一遍分解得到的若干问题仍然很复杂,则可以继续分解直至可以求解为止。下面我们就从分治思想的角度介绍归并排序快速排序

二、归并排序

  1. 基本思想:有点“分解并征服/Divide and Conquer”的意思,具体步骤如下:
    (1)将一个序列分成两个子序列,并排序两个子序列
    (2)重新组合两个子序列使成为一个有序的序列
    (3)下图可以形象的展示分解及组合的过程(来源于百度百科):
    这里写图片描述
  2. 代码实现(C++):
void mergeTwoArray(int arrayName[], int p, int q, int r);
//to  merge arrayName[p...q] and arrayName[q+1...r], both in ascending order
void mergeSort(int arrayName[], int low, int high);
//to sort "arrayName" between low and high

void mergeTwoArray(int arrayName[], int p, int q, int r)
{
    int assistArray[1000];
    int s = p;
    int t = q + 1;
    //initialize two indicators to point at the beginning of two arrays
    int k = p;
    while ((s <= q) && (t <= r))
    {
        if (arrayName[s] <= arrayName[t])
        {
            assistArray[k] = arrayName[s];
            s += 1;
        }
        else
        {
            assistArray[k] = arrayName[t];
            t += 1;
        }
        k += 1;
    }
    if (s == q + 1)
        for (k, t;k <= r;k++, t++)
            assistArray[k] = arrayName[t];
    else
        for (k, s;k <= r;k++, s++)
            assistArray[k] = arrayName[s];
    for (p;p <= r;p++)
        arrayName[p] = assistArray[p];
}

void mergeSort(int arrayName[], int low, int high)
{
    int mid = 0;
    if (low < high)
    {
        mid = (low + high) / 2;
        mergeSort(arrayName, low, mid);
        mergeSort(arrayName, mid + 1, high);
        mergeTwoArray(arrayName, low, mid, high);
    }
}

3.时间复杂度为θ(nlogn):
这里写图片描述

三、快速排序

  1. 基本思想:将一个序列分解成两个子序列,其中一个子序列的元素比另外一个子序列的元素都要小。为了完成这种目标,我们可以在一个待分解的序列中找到一个参考点(称之为支点,pivot)。下图是一个例子:
    这里写图片描述
  2. 代码实现(C++)
void swapValues(int arrayName[], int i, int j); 
//swap the values of arrayName[i] and arrayName[j]
int splitArray(int arrayName[], int low, int high);
//to split an array between low and high and return the new position of the pivot
void quickSort(int arrayName[], int low, int high);
//to sort "arrayName" between low and high

void swapValues(int arrayName[], int i, int j)
{
    int middleVariable = 0;
    middleVariable = arrayName[i];
    arrayName[i] = arrayName[j];
    arrayName[j] = middleVariable;
}

int splitArray(int arrayName[], int low, int high)
{
    int i = low;
    int x = arrayName[low];
    for (int j = low + 1;j <= high;j++)
        if (arrayName[j] <= x)
        {
            i += 1;
            if (i != j)
                swapValues(arrayName, i, j);
        }
    swapValues(arrayName, low, i);
    return i;
}

void quickSort(int arrayName[], int low, int high)
{
    if (low < high)
    {
        int w = splitArray(arrayName, low, high);
        //"w" represents the new position of the pivot in a spliting
        quickSort(arrayName, low, w - 1);
        quickSort(arrayName, w + 1, high);
    }
}

3.时间复杂度:θ(nlogn)。

算法包
      点击这里下载排序算法源代码,包括:插入排序、选择排序、冒泡排序、快速排序、归并排序、0交换排序等多种算法,以整数序列为例实现。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值