zoukankan      html  css  js  c++  java
  • 快速排序Quick sort

    快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

    步骤为:

    1. 从数列中挑出一个元素,称为 "基准"(pivot),(定基准,有随机版本)
    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作(分割操作) 
    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。(递归实现)

    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    从别人的博客里知道了三种版本的快排。

    代码一:霍尔快排

    /*
     * Author: Tanky Woo
     * Blog:   www.WuTianQi.com
     * Note:   快速排序版本1 --- Hoare-Partition
     */
     
    #include <iostream>
    using namespace std;
     
    int num;
     
    void swap(int &a, int &b)    
    {
        int temp = a;
        a = b;
        b = temp;
    }
     
    void PrintArray(int *arr)
    {
        for(int i=1; i<=num; ++i)
            cout << arr[i] << " ";
        cout << endl;
    }
     
    int Partition1(int *arr, int beg, int end)
    {
        int low = beg, high = end;
        int sentinel = arr[beg];
        while(low < high)
        {
            while(low<high && arr[high]>=sentinel)
                --high;
            arr[low] = arr[high];
            while(low<high && arr[low]<=sentinel)
                ++low;
            arr[high] = arr[low];
        }
        arr[low] = sentinel;
     
        cout << "排序过程:";
        PrintArray(arr);
        return low;
    }
     
    void QuickSort(int *arr, int beg, int end)
    {
        if(beg < end)
        {
            int pivot = Partition1(arr, beg, end);
            QuickSort(arr, beg, pivot-1);
            QuickSort(arr, pivot+1, end);
        }
    }
     
    int main()
    {
        int arr[100];
        cout << "Input the num of the elements:
    ";
        cin >> num;
        cout << "Input the elements:
    ";
        for(int i=1; i<=num; ++i)
            cin >> arr[i];
        QuickSort(arr, 1, num);
        cout << "最后结果:";
        PrintArray(arr);
        return 0;
    }        

    代码二:算法导论当中的快排

    /*
     * Author: Tanky Woo
     * Blog:   www.WuTianQi.com
     * Note:   快速排序版本2---《算法导论》
     */
     
    #include <iostream>
    using namespace std;
     
    int num;
     
    void swap(int &a, int &b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
     
    void PrintArray(int *arr)
    {
        for(int i=1; i<=num; ++i)
            cout << arr[i] << " ";
        cout << endl;
    }
     
    int Partition2(int *arr, int beg, int end)
    {
        int sentinel = arr[end];
        int i = beg-1;
        for(int j=beg; j<=end-1; ++j)
        {
            if(arr[j] <= sentinel)
            {
                i++;
                swap(arr[i], arr[j]);
            }
        }
        swap(arr[i+1], arr[end]);
     
        cout << "排序过程:";
        PrintArray(arr);
        return i+1;
    }
     
    void QuickSort(int *arr, int beg, int end)
    {
        if(beg < end)
        {
            int pivot = Partition2(arr, beg, end);
            QuickSort(arr, beg, pivot-1);
            QuickSort(arr, pivot+1, end);
        }
    }
     
    int main()
    {
        int arr[100];
        cout << "Input the num of the elements:
    ";
        cin >> num;
        cout << "Input the elements:
    ";
        for(int i=1; i<=num; ++i)
            cin >> arr[i];
        QuickSort(arr, 1, num);
        cout << "最后结果:";
        PrintArray(arr);
        return 0;
    }

    随机化快排:

    /*
     * Author: Tanky Woo
     * Blog:   www.WuTianQi.com
     * Note:   快速排序版本3 --- 随机化版本
     * 解决待排序元素相差很大的情况
     */
     
     
    #include <iostream>
    #include <cstdlib>
    using namespace std;
     
    int num;
     
    void swap(int &a, int &b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
     
    void PrintArray(int *arr)
    {
        for(int i=1; i<=num; ++i)
            cout << arr[i] << " ";
        cout << endl;
    }
     
    int Partition3(int *arr, int beg, int end)
    {
        int sentinel = arr[end];
        int i = beg-1;
        for(int j=beg; j<=end-1; ++j)
        {
            if(arr[j] <= sentinel)
            {
                i++;
                swap(arr[i], arr[j]);
            }
        }
        swap(arr[i+1], arr[end]);
     
        cout << "排序过程:";
        PrintArray(arr);
        return i+1;
    }
     
    int RandomPartition(int *arr, int beg, int end)
    {
        int i = beg + rand() % (end-beg+1);
        swap(arr[i], arr[end]);
        return Partition3(arr, beg, end);
    }
     
     
    void RandomQuickSort(int *arr, int beg, int end)
    {
        if(beg < end)
        {
            int pivot = RandomPartition(arr, beg, end);
            RandomQuickSort(arr, beg, pivot-1);
            RandomQuickSort(arr, pivot+1, end);
        }
    }
     
    int main()
    {
        int arr[100];
        cout << "Input the num of the elements:
    ";
        cin >> num;
        cout << "Input the elements:
    ";
        for(int i=1; i<=num; ++i)
            cin >> arr[i];
        RandomQuickSort(arr, 1, num);
        cout << "最后结果:";
        PrintArray(arr);
        return 0;
    }

    随机化的快排一般适用于待排序的数据之间相差较大的情况下。

    模版:

     1 /*
     2 快速排序:模版 
     3  */
     4  
     5 #include <iostream>
     6 using namespace std;
     7 
     8  
     9 void swap(int *a, int *b)
    10 {
    11     int temp = *a;
    12     *a = *b;
    13     *b = temp;
    14 }
    15  
    16 int Partition(int *arr, int beg, int end)
    17 {
    18     int sentinel = arr[end];
    19     int i = beg-1;
    20     for(int j=beg; j<=end-1; ++j)
    21     {
    22         if(arr[j] <= sentinel)
    23         {
    24             i++;
    25             swap(&arr[i], &arr[j]);
    26         }
    27     }
    28     swap(&arr[i+1], &arr[end]);
    29     return i+1;
    30 }
    31  
    32 void QuickSort(int *arr, int beg, int end)
    33 {
    34     if(beg < end)
    35     {
    36         int pivot = Partition(arr, beg, end);
    37         QuickSort(arr, beg, pivot-1);
    38         QuickSort(arr, pivot+1, end);
    39     }
    40 }
  • 相关阅读:
    facade 对于有很多接口的提供一个简单的接口
    UML 常用符号 转
    <html> 按钮换行
    javascript: change the content of table
    [转载]当今计算机软件开发和应用领域最重要十种关键技术
    括号匹配算法
    求出给定两日期段 之间的交集算法
    表中的数据导出为insert语句的简单方法
    投色子下注的小程序
    未来社会发展趋势__P2p时代
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3248812.html
Copyright © 2011-2022 走看看