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

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

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

复杂度

排序算法 平均时间复杂度 最坏时间复杂度 最好时间复杂度 空间复杂度 稳定性
快速排序 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

posted @ 2020-09-19 20:46  trafalgar999  阅读(129)  评论(0编辑  收藏  举报