簡單實用的c++快速排序模板類
(一)目標
在實際問題的解決過程中,我們發現,很多問題都可以歸結為對數據的排序和查詢。而查詢的效率則在很大程度上依賴于排序的效率;尤其是在數據量達到海量級的時候。因此,設計一個有效的排序算法是至關重要的。本文設計了一個通用的c++ quicksort 模板類。通過簡單的提供一個Data類,可以實現任意數據的快速排序算法,提高了開發效率。
(二)快速排序算法的思想
最基本的快速排序的思想是基于分治策略的:
對于輸入的子序列
L[p..r],如果規模足夠小則直接進行排序,否則分三步處理:
1 分解(Divide):將輸入的序列L[p..r]劃分成兩個非空子序列L[p..q]和L[q+1..r], 使L[p..q]中任一元素
的值不大于L[q+1..r]中任一元素的值。
2 遞歸
求解(Conquer):通過遞歸調用快速排序算法分別對L[p..q]和L[q+1..r]進行排序。
3 合并(Merge):由于對分解出的兩個子序列的排序是就地進行的, 所以在L[p..q]和L[q+1..r]都排好序后不需要執行任何計算L[p..r]就已排好序。
(三)準備工作和源代碼
1 使用vc6建立console工程
2 加入下面的模板類:
template<typename DataType>//DataType是模板參數,代表了欲排序的數據類型
class QuickSortTemp
{
public:
QuickSortTemp()
{
}
~QuickSortTemp()
{
}
public:
// 快速排序的實現,Array是要排序數據的數組,nLower,nUpper范圍是0 ~ 數據總個數-1
static void QuickSort(DataType* Array, int nLower, int nUpper)
{
// 測試是否排序完畢
if (nLower < nUpper)
{
// 分解和分別進行排序
int nSplit = Partition (Array, nLower, nUpper);//數據切分為兩個部分
QuickSort (Array, nLower, nSplit - 1);//左半部分遞歸排序
QuickSort (Array, nSplit + 1, nUpper);//右半部分遞歸排序
}
}// 切分數據為左右兩個部分,返回中間元素x的編號
// 主要的過程就是:選擇一個元素x作為分界點,將比x大的元素放到x右邊,其余放到x左邊。
static int Partition (DataType* Array, int nLower, int nUpper)
{
int nLeft = nLower + 1;
DataType Pivot = Array[nLower];
int nRight = nUpper;
DataType Swap;
while (nLeft <= nRight)
{
while (nLeft <= nRight && Array[nLeft].CompareTo(Pivot) <= 0)
nLeft = nLeft + 1;
while (nLeft <= nRight && Array[nRight].CompareTo(Pivot) > 0)
nRight = nRight - 1;
if (nLeft < nRight)
{
Swap = Array[nLeft];
Array[nLeft] = Array[nRight];
Array[nRight] = Swap;
nLeft = nLeft + 1;
nRight = nRight - 1;
}
}
Swap = Array[nLower];
Array[nLower] = Array[nRight];
Array[nRight] = Swap;
return nRight;
}
};以上就實現了快速排序的模板類。
3 數據類接口的實現
從上面模板類的實現我們可以看出,為了使用這個模板類對某種類型的數據數組DataType * data進行排序,我們必須實現DataType的接口CompareTo(比較兩個DataType 元素a,b的大小,a>b返回1,a==b返回0,否則返回-1)。
舉個例子來說:現在要排序二維點坐標,定義大小關系是:先比較x軸坐標值大小,x相同的話,由y值大小決定大小關系。即:(1,1) == (1,1) , (2,1) > (1, 10) , (3, 5) < (4, 1)。
此外:還必須實現DataType類型的無參數的默認構造函數
定義數據類型MyPoint如下:
struct MyPoint
{
MyPoint()
{
}
MyPoint(int x, int y)
{
this->x = x;
this->y = y;
}
int CompareTo(MyPoint& b)
{
if(this->x < b.x)
return -1;
else if(this->x > b.x)
return 1;
else
{
if(this->y > b.y)
return 1;
else if(this->y < b.y)
return -1;
else
return 0;
}
}
int x;
int y;
};(四)測試
下面是用于測試的主函數:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
//Point數組
MyPoint points[10] = {MyPoint(1,1), MyPoint(2,5), MyPoint(7,11), MyPoint(100,2),
MyPoint(1, 7), MyPoint(9,32), MyPoint(7, 1), MyPoint(2,2),
MyPoint(1,1), MyPoint(9,5)};
int count = 10;
//排序前
printf("before quicksort:/n");
for(int i = 0 ; i <count ; i ++)
printf("%d <-------> (%d,%d)/n", i, points[i].x, points[i].y);
//調用模板類排序
QuickSortTemp<MyPoint>::QuickSort(points, 0, count - 1);
//排序后
printf("after quicksort:/n");
for(i = 0 ; i <count ; i ++)
printf("%d <-------> (%d,%d)/n", i, points[i].x, points[i].y);
system("pause");
return nRetCode;
}結果輸出如下:
before quicksort:
0 <-------> (1,1)
1 <-------> (2,5)
2 <-------> (7,11)
3 <-------> (100,2)
4 <-------> (1,7)
5 <-------> (9,32)
6 <-------> (7,1)
7 <-------> (2,2)
8 <-------> (1,1)
9 <-------> (9,5)
after quicksort:
0 <-------> (1,1)
1 <-------> (1,1)
2 <-------> (1,7)
3 <-------> (2,2)
4 <-------> (2,5)
5 <-------> (7,1)
6 <-------> (7,11)
7 <-------> (9,5)
8 <-------> (9,32)
9 <-------> (100,2)
請按任意鍵繼續 . . .
(五)說明
本文根據快速排序算法,實現了一個c++快速排序模板類。使用這個模板類,并遵守欲排序數據類型必須實現的接口定義,就能實現對任意數據類型的快速排序。當然,本文的例子只是一個基本的引導。
作者:
RDIF
出處:
http://www.rzrgm.cn/huyong/
Email:
406590790@qq.com
QQ:
406590790
微信:
13005007127(同手機號)
框架官網:
http://www.guosisoft.com/
http://www.rdiframework.net/
框架其他博客:
http://blog.csdn.net/chinahuyong
http://www.rzrgm.cn/huyong
國思RDIF開發框架
,
給用戶和開發者最佳的.Net框架平臺方案,為企業快速構建跨平臺、企業級的應用提供強大支持。
關于作者:系統架構師、信息系統項目管理師、DBA。專注于微軟平臺項目架構、管理和企業解決方案,多年項目開發與管理經驗,曾多次組織并開發多個大型項目,在面向對象、面向服務以及數據庫領域有一定的造詣。現主要從事基于
RDIF
框架的技術開發、咨詢工作,主要服務于金融、醫療衛生、鐵路、電信、物流、物聯網、制造、零售等行業。
如有問題或建議,請多多賜教!
本文版權歸作者和CNBLOGS博客共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,可以通過微信、郵箱、QQ等聯系我,非常感謝。

浙公網安備 33010602011771號