排序算法:快速排序和归并排序

排序算法:快速排序和归并排序

快速排序和归并排序是排序算法里十分常用的两个排序,二者的代码复杂度差不多,并且都应用了分治法的思想。

复杂度

排序算法平均时间复杂度最坏时间复杂度最好时间复杂度空间复杂度稳定性
快速排序O(nlogn)O(n²)O(nlogn)O(1)不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定

快速排序

快速排序简称快排,思想是首先选定要排序的那组数的一个元素作为基准,可以是第一个元素,最后一个元素,或者是中间的元素,然后遍历所有元素,遍历的过程中,要把所有小于基准的元素放在基准的前面,反之放在基准后面,一轮遍历结束之后,我们可以保证在这组元素中,被选为基准的元素一定已经排好序了,紧接着就对基准前面的所有元素和基准后面的所有元素继续这一过程,直到所有元素排好序。

quickSort

代码:

c++版本:

void quick_sort(int q[], int l, int r)	// q是待排序的数组,l和r是要排序的范围,且l,r都是数组有效的索引
{
    if (l >= r)	//递归结束条件
        return;

    int x = q[(l + r) / 2], i = l - 1, j = r + 1;	//选定基准,让i,j位于初始位置
    while (i < j)
    {
        do
            i++;
        while (q[i] < x);
        do
            j--;
        while (q[j] > x);
        if (i < j)
            swap(q[i], q[j]);
    }

    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

JavaScript版本:

function swap(arr, i, j) {
    let c = arr[i];
    arr[i] = arr[j];
    arr[j] = c;
  }
function quickSort(arr, l, r) {
    if (l >= r) return;
    let i = l - 1;
    let j = r + 1;
    let x = arr[Math.floor((l + r) / 2)];

    while (i < j) {
      while (arr[++i] < x);
      while (arr[--j] > x);
      if (i < j) {
        swap(arr, i, j);
      }
    }
    quickSort(arr, l, j), quickSort(arr, j + 1, r);
  }

归并排序

归并排序首先让数组中的每一个数单独成为长度为1的区间,然后两两一组有序合并,得到长度为2的有序区间,依次进行,直到合成整个区间。

mergesort

c++版本:

void mergeSort(int q[], int l, int r)
{
    if (l >= r)
        return;

    int mid = l + r >> 1;

    mergeSort(q, l, mid), mergeSort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j])
            tmp[k++] = q[i++];
        else
            tmp[k++] = q[j++];

    while (i <= mid)
        tmp[k++] = q[i++];
    while (j <= r)
        tmp[k++] = q[j++];

    for (i = l, j = 0; i <= r; i++, j++)
        q[i] = tmp[j];
}

JavaScript版本:

  let merge_tmp = [];
  function mergeSort(arr, l, r) {
    if (l >= r) return;
    let mid = Math.floor((l + r) / 2);
    mergeSort(arr, l, mid), mergeSort(arr, mid + 1, r);
    let k = 0,
      i = l,
      j = mid + 1;
    while (i <= mid && j <= r) {
      if (arr[i] <= arr[j]) merge_tmp[k++] = arr[i++];
      else merge_tmp[k++] = arr[j++];
    }
    while (i <= mid) merge_tmp[k++] = arr[i++];
    while (j <= r) merge_tmp[k++] = arr[j++];

    for (let i = l, j = 0; i <= r; i++, j++) arr[i] = merge_tmp[j];
  }

date: 2020/9/19

author: trafal

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值