zoukankan      html  css  js  c++  java
  • 《数据结构与算法分析:C语言描述》复习——第六章“排序”——快速排序

    2014.06.17 05:15

    简介:

      快速排序是实际应用最广的基于内存的不稳定的比较排序。拥有O(n * log(n))的平均复杂度和O(n^2)的最坏复杂度。采用的思路是分治法,递归实现。

    描述:

      快速排序的基本思路,是从数组中选取一个值pivot作为参照,使得比pivot小的都在它左边,比pivot大的都在它右边。pivot的英文意思是支点,从这个你应该能猜到——左右的元素最好数目接近。如果偏向很多,效果就不好了。如此递归排序两个小段,就可以完成整个数组的排序了。思路很简单,实现起来却不是那么简单。讲解快速排序的原理也许得废很多话,不如逐行仔细阅读代码,体会每一步执行的过程。我认为这其中最难理解的,莫过于++和--之处。由于实现快速排序的难度,光是“写个快排看看”就算是一道面试题了。

      由于我曾经在面试时被直接要求写出快速排序,当时的我完全无力招架(那时可以说基本不会写代码,而且还自我感觉良好)。所以现在一提到快速排序我就非常小心,几乎是按照教材上的代码实现的。在这段不算长的代码中随便改掉一点,都容易造成各种错误。实际上我在别人的不少技术博客中的确找到了错误,有些运行结果明显不对,但代码长得和正确版本几乎一模一样。这应该就是那种很不直观,但代码简洁的神级之算法吧。

    实现:

     1 // My implementation for quick sort.
     2 #include <iostream>
     3 #include <vector>
     4 using namespace std;
     5 
     6 const int CUT_OFF = 4;
     7 
     8 static void swap(int &x, int &y)
     9 {
    10     int tmp;
    11     
    12     tmp = x;
    13     x = y;
    14     y = tmp;
    15 }
    16 
    17 static int medianThree(vector<int> &v, int left, int right)
    18 {
    19     int center = (left + right) / 2;
    20     
    21     if (v[left] > v[right]) {
    22         swap(v[left], v[right]);
    23     }
    24     if (v[left] > v[center]) {
    25         swap(v[left], v[center]);
    26     }
    27     if (v[center] > v[right]) {
    28         swap(v[center], v[right]);
    29     }
    30     swap(v[center], v[right - 1]);
    31     
    32     return v[right - 1];
    33 }
    34 
    35 static void quickSortRecursive(vector<int> &v, int left, int right)
    36 {
    37     if (right - left + 1 >= CUT_OFF) {
    38         int i, j;
    39         int pivot = medianThree(v, left, right);
    40         
    41         i = left;
    42         j = right - 1;
    43         while (true) {
    44             while (v[++i] < pivot) {}
    45             while (v[--j] > pivot) {}
    46             if (i < j) {
    47                 swap(v[i], v[j]);
    48             } else {
    49                 break;
    50             }
    51         }
    52         swap(v[i], v[right - 1]);
    53         quickSortRecursive(v, left, i - 1);
    54         quickSortRecursive(v, i + 1, right);
    55     } else {
    56         int i, j;
    57         int tmp;
    58         
    59         for (i = left + 1; i <= right; ++i) {
    60             tmp = v[i];
    61             for (j = i; j > left && v[j - 1] > tmp; --j) {
    62                 v[j] = v[j - 1];
    63             }
    64             v[j] = tmp;
    65         }
    66     }
    67 }
    68 
    69 void quickSort(vector<int> &v)
    70 {
    71     int n = (int)v.size();
    72     quickSortRecursive(v, 0, n - 1);
    73 }
    74 
    75 int main()
    76 {
    77     vector<int> v;
    78     int n, i;
    79     
    80     while (cin >> n && n > 0) {
    81         v.resize(n);
    82         for (i = 0; i < n; ++i) {
    83             cin >> v[i];
    84         }
    85         quickSort(v);
    86         for (i = 0; i < n; ++i) {
    87             cout << v[i] << ' ';
    88         }
    89         cout << endl;
    90     }
    91     
    92     return 0;
    93 }
  • 相关阅读:
    菜鸡学习之路之并查集
    Leetcode 28. 实现 strStr() python3
    Leedcode 67. 二进制求和 python3
    2020 高校战“疫”网络安全分享赛 misc ez_mem&dump & 隐藏的信息
    leetcode 709.转换成小写字母
    2020 MetasequoiaCTF 部分misc
    Linux任务在后台运行
    Linux网络监控(netstat)
    Linux中wget资源下载
    Linux远程登录+远程发送文件
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3792087.html
Copyright © 2011-2022 走看看