快速排序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:\n";
    cin >> num;
    cout << "Input the elements:\n";
    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:\n";
    cin >> num;
    cout << "Input the elements:\n";
    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:\n";
    cin >> num;
    cout << "Input the elements:\n";
    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 }

 

posted @ 2013-08-09 17:50  Geekers  阅读(260)  评论(0编辑  收藏  举报