• QuickSort(快速排序)原理及C++代码实现


    快速排序可以说是最重要的排序,其中延伸的思想和技巧非常值得我们学习。

    快速排序也使用了分治的思想,原理如下:

    分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。其中计算下标q也是划分过程的一部分。

    解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。

    合并:因为子数组都是原址排序的,所以不需要合并操作,数组A[p..r]已经有序。

    只要划分不是极端的,那么快速排序的时间复杂度为O(nlgn),否则时间复杂度为θ(n2)。

    可以利用随机化思想(随机选择主元)来使快速排序的期望时间复杂度达到O(nlgn)。

    快速排序不是稳定排序。

    代码如下:(仅供参考)

     1 int Partition(int * const begin, int * const end) { //lomuto划分
     2     int i = -1;
     3     for (int j = 0; j < (end - begin); ++j) {
     4         if (*(begin + j) <= *(end - 1)) {       //以最后一个值为关键值划分
     5             ++i;
     6             swap(*(begin + i), *(begin + j));
     7         }
     8     }
     9     return i;
    10 }
    11 
    12 void QuickSort(int * const begin, int * const end) {
    13     if (begin >= end - 1)
    14         return ;
    15     int mid = Partition(begin, end);
    16     QuickSort(begin, begin + mid);    //调用的是lomute划分,因为lomuto划分结束以后
    17     QuickSort(begin + mid + 1, end);  //mid一定在它应该在的位置
    18 }
    1 void QuickSort(int * begin, int * const end) {  //尾递归
    2     while (begin < end - 1) {
    3         int mid = Partition(begin, end);
    4         QuickSort(begin, begin + mid);    //调用的是lomute划分
    5         begin = begin + mid + 1;
    6     }
    7 }

    另外一种划分方法:

     1 int Partition(int * const begin, int * const end) { //hoare划分
     2     int key = *begin;         //以第一个值为关键值划分
     3     int i = -1, j = end - begin;  //i, j根本不会越界
     4     while (1) {
     5         for (++i; *(begin + i) < key; ++i); //可看做do{}while;
     6         for (--j; *(begin + j) > key; --j);
     7         if (i < j)
     8             swap(*(begin + i), *(begin + j));
     9         else
    10             return j;
    11     }
    12 }
    13 
    14 void QuickSort(int * const begin, int * const end) {
    15     if (begin >= end - 1)
    16         return ;
    17     int mid = Partition(begin, end);
    18 
    19     QuickSort(begin, begin + mid + 1);   //调用hoare划分,因为hoare划分只能保证
    20     QuickSort(begin + mid + 1, end);     //mid(包括mid)以前的元素小于等于mid以后的元素
    21 }
  • 相关阅读:
    [Android 4.4.4] 泛泰A850 三版通刷 Mokee4.4.4 KTU84P 20140626 RC2.2 by syhost
    YUV12(420) (from)to RGB24
    Python图像处理(16):图像金字塔
    内存管理笔记(分页,分段,逻辑地址,物理地址)【转】
    Linux内核分析--内核中的数据结构双向链表【转】
    标准IO与文件IO 的区别【转】
    Linux中设备号及设备文件【转】
    静态编译和动态编译的区别【转】
    嵌入式系统 Boot Loader 技术内幕【转】
    理解 Linux 的硬链接与软链接【转】
  • 原文地址:https://www.cnblogs.com/yxsrt/p/12193638.html
Copyright © 2020-2023  润新知