其實這一篇我老早就寫過了,只不過最近在總結《算法導論》,而第七章就是快速排序,我當初總結的快排也是根據算法導論來的,為了方便大家閱讀,我在這里把曾經寫過的重新再貼一遍。
前幾天寫過一個堆排序的文章(http://www.wutianqi.com/?p=1820),里面謝了很多講解和代碼注釋,個人感覺快速排序不是很難,所以不想寫講解,也不需要寫注釋,大家如果不明白什么是快速排序,可以去看下文章最后我推薦的幾個鏈接。
我查過網上很多關于快排的文章和代碼,但是基本都是最原始的快排,即霍爾(Hoare)快排。想必大家也沒有注意這些,我準備把霍爾快排,算法導論上的快排和隨機化快排的代碼一起發出來,供大家對比與學習,歡迎大家和我探討
代碼一.霍爾快排:
/*
* 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: 快速排序版本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: 快速排序版本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;
}
* 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.http://bbs.chinaunix.net/viewthread.php?tid=1011316
算是一個討論帖。很給力!
2.http://www.javaeye.com/topic/561718
講得比較詳細,不過代碼是Java的。
3.http://tayoto.blog.hexun.com/25048556_d.html
4.http://www.360doc.com/content/10/1106/11/1317564_67067368.shtml
概念上很詳細。
5.http://blog.csdn.net/wssxy/archive/2008/12/05/3448642.aspx
一篇講快排的佳作!
6.http://www.cnblogs.com/chinazhangjie/archive/2010/12/09/1901491.html
小杰的文章,用C++模板類寫的。大家可以去學習學習。
在我獨立博客上的原文:http://www.wutianqi.com/?p=2368
歡迎大家互相學習,互相探討。