快速排序與隨機快速排序

2022-08-03 07:27:10 字數 3979 閱讀 1993

實現對陣列的普通快速排序與隨機快速排序。

(1)實現上述兩個演算法 

(2)統計演算法的執行時間

(3)分析效能差異,作出總結

(一)快速排序

通過使用分治思想對快速排序演算法進行描述。下面對乙個典型的子陣列a[p…r]進行快速排序的三步分治過程:

分解:陣列a[p…r]被劃分為兩個(可能為空)子陣列a[p…q-1]和a[q+1…r],使得a[p…q-1]中的每乙個元素都小於等於a[q],而a[q]也小於等於a[q+1…r]中的每個元素。其中,計算下標q也是劃分過程的一部分。

解決:通過遞迴呼叫快速排序,對於陣列a[p…q-1]和a[q+1…r]進行排序。

合併:因為子陣列都是原址排序的,所以不需要合併操作:陣列a[p…r]已近有序。

關鍵**實現:

(一)實現快速排序:

quicksort(a,p,r)

1 if p < r

2     q = partition(a,p,r)

3     quicksort(a,p,q-1)

4     quicksort(a,q+1,r)

(二)陣列的劃分:

partition(a,p,r)

1 x = a[r]

2 i = p-1

3 for j = p to r-1

4     if a[j] <= x

5         i = i + 1

6         exchange a[i]with a[j]

7 exchange a[i+1] with a[r]

8 return i+1

(二)隨機快速排序

隨機快速排序與始終採用a[r]作為主元的方法不同,通過採用一種隨機抽樣的隨機化技術,使得從子陣列a[p…r]中隨機選擇乙個元素作為主元。為達到這一目的,首先將a[r]從a[p…r]中隨機選出的乙個元素交換。通過對序列p,…,r的隨機抽樣,我們可以保證主元元素x=a[r]是等概論地從子陣列的r-p+1個元素中選取的,由於主元素是隨機選取的,使得對輸入陣列的劃分也是比較均衡的,從而獲得較好的期望效能。 

關鍵**實現:

(一)隨機數組的呼叫:

randomized-partition(a,p,r)

1 i = random(p,r)

2 exchange a[r] with a[i]

3 return partition(a,p,r)

(二)函式partition(a,p,r)仍呼叫快速排序的partitoon(a,p,r)函式

說明:快速排序過程中,呼叫quicksort()和partition()函式進行陣列內部的快速排序;對於隨機快速排序,則呼叫randomized-partition()來選取隨機的關鍵字(key),再通過quicksort()和partition()函式進行排序。

10個元素快速排序的實驗結果:

10000個元素快速排序的實驗結果:

10個元素隨機快速排序的實驗結果:

10000個元素隨機快速排序的實驗結果:

(一)從原理上分析,快速排序的最壞執行時間是θ(n2),即在每次進行partition(a,p,r)函式對陣列a進行劃分時,都出現主元素在劃分區域的某一側,使得劃分區域的元素都小於或大於主元素;期望執行時間是θ(nlgn),在隨機快速排序中,執行randomized_partition(a,p,r)後每次選取主元素都能使得主元素在劃分區域的中間。

(二)從實際的執行過程中,實驗隨機生成10、10000個資料進行排序,並比較了執行排序**的時間。實驗出現中,執行時間未出現較大區分度的原因:一方面是因為在普通快速排序過程中,陣列是隨機生成的,這樣使得在每次選取主元時,和隨機快速排序相似,從而二者區分度不高;另一方面,電腦主頻較高、選取的實驗資料不夠大也會使二者區分度不高。

附錄(**)

(一)普通快速排序

#include #include 

#include

#define max 10000

#define clocks_pre_sec ((clock_t)1000)

void quicksort(int array, int p, intr)}

int partition(int array, int p, int

r) }

m =array[i+1

]; array[i+1] =array[r];

array[r] =m;

return (i+1);}

intmain()

printf(

"\nquicksortresult:\n");

start =clock();

quicksort(array,

0 ,max-1

); finish =clock();

for(i = 0; i< max; i++)

printf(

"%d\n

",array[i]);

thetimes =(double)((finish - start)/clocks_pre_sec);

printf(

"thetime of quicksort is:%fs!\n

",thetimes);

}

(二)隨機快速排序

1 #include 2

3 #include 4

5 #include 678

9#define max 1000

1011

#define clocks_pre_sec ((clock_t)1000)

1213

1415

int random_partition(int array, int p, int

r)16

1734

3536

37void random_quicksort(int array, int p, int

r)38

395455}

5657

5859

int partition(int array, int p, int

r)60

618687}

8889 m =array[i+1

];90

91 array[i+1] =array[r];

9293 array[r] =m;

9495

9697

return (i+1

);9899}

100101

102103

intmain()

104105

128129 printf("

random_quicksortresult:\n");

130131

132133 start =clock();

134135 random_quicksort(array,0 ,max-1

);136

137 finish =clock();

138139

140141

for(i = 0; i< max; i++)

142143 printf("

%d\n

",array[i]);

144145 thetimes = (double)((finish- start)/clocks_pre_sec);

146147 printf("

thetime of random_quicksort is:%fs!\n

",thetimes);

148149 }

快速排序和隨機快速排序

嚴書上的快排是以最左邊元素為樞紐的,如下 include include using namespace std intpartition int a,int left,int right a left p return left void quicksort int a,int left,int ...

隨機快速排序

問題畫出來小於區域和等於區域,劃偏 1,2,3,4,5,6,7 7 7 總拿最後乙個劃分,跟資料狀況有關,比較差的蛻變程o n 2 6,5,4,3,2,1 1,1 資料分布比較差 比價好的情況 x t n 2t n 2 o n n nlogn 隨機快速排序 隨機選擇乙個數和最後乙個替換一下 長期期望...

經典快速排序演算法與隨機快速排序演算法

快速排序用到了分治思想,同樣的還有歸併排序。乍看起來快速排序和歸併排序非常相似,都是將問題變小,先排序子串,最後合併。不同的是快速排序在劃分子問題的時候經過多一步處理,將劃分的兩組資料劃分為一大一小,這樣在最後合併的時候就不必像歸併排序那樣再進行比較。但也正因為如此,劃分的不定性使得快速排序的時間複...