快速排序算法

快速排序(Quicksort)是對冒泡排序的一種改進。是由C. A. R. Hoare在1962年提出的一種劃分交換排序,它採用了一種分治的策略,通常稱其爲分治法(Divide-and-ConquerMethod)。[1]它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

一、算法介紹

設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作爲關鍵數據,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱爲一趟快速排序。值得注意的是,快速排序不是一種穩定的排序算法,也就是說,多個相同的值的相對位置也許會在算法結束時產生變動。

一趟快速排序的算法是:

1)設置兩個變量i、j,排序開始的時候:i=0,j=N-1;

2)以第一個數組元素作爲關鍵數據,賦值給key,即key=A[0];

3)從j開始向前搜索,即由後開始向前搜索(j--),找到第一個小於key的值A[j],將值爲key的項與A[j]交換;

4)從i開始向後搜索,即由前開始向後搜索(i++),找到第一個大於key的A[i],將值爲key的項與A[i]交換;

5)重複第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[j]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到爲止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令循環結束)。

例如:待排序的數組A的值分別是:(初始關鍵數據:X=49) 注意關鍵X永遠不變,永遠是和X進行比較,無論在什麼位置,最後的目的就是把X放在中間小的放前面大的放後面。

A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:

49 38 65 97 76 13 27

進行第一次交換後: 27 38 65 97 76 13 49

( 按照算法的第三步從後面開始找)

進行第二次交換後: 27 38 49 97 76 13 65

( 按照算法的第四步從前面開始找>X的值,65>49,兩者交換,此時:I=3 )

進行第三次交換後: 27 38 13 97 76 49 65

( 按照算法的第五步又一次執行算法的第三步從後開始找)

進行第四次交換後: 27 38 13 49 76 97 65

( 按照算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時:J=4 )

此時再執行第三步的時候就發現I=J,從而結束一趟快速排序,那麼經過一趟快速排序之後的結果是:27 38 13 49 76 97 65,即所以大於49的數全部在49的後面,所以小於49的數全部在49的前面。

快速排序就是遞歸調用此過程——在以49爲中點分割這個數據序列,分別對前面一部分和後面一部分進行類似的快速排序,從而完成全部數據序列的快速排序,最後把此數據序列變成一個有序的序列,根據這種思想對於上述數組A的快速排序的全過程:

初始狀態 {49 38 65 97 76 13 27}

進行一次快速排序之後劃分爲 {27 38 13} 49 {76 97 65}

分別對前後兩部分進行快速排序 {27 38 13} 經第三步和第四步交換後變成 {13 27 38} 完成排序。

{76 97 65} 經第三步和第四步交換後變成 {65 76 97} 完成排序。

二、代碼模板演示

#include<stdio.h> 

#include<math.h>
#include<iostream>
#include<stdlib.h> 
#include<string.h>
using namespace std;


qSort(int *a,int left,int right)
{
if(left < right){
int l = left;
int r = right;
int k = a[left];
while(l < r)
{
while(l < r && a[r] > k)
r--;
a[l] = a[r];
while(l < r && a[l] < k)
l++;
a[r] = a[l];
}
a[l] = k;
qSort(a,left,l-1);
qSort(a,l+1,right);
}

}
int comp(const void*a,const void*b)
{
return *(int*)a - *(int*)b;//若爲從大到小改爲return *(int*)b - *(int*)a;
}
int main()
{
int a[256];
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%d",&a[i]);
}
/*
第一種:自己編寫快排函數qSort
注意:採用分治思想,定義第一個數字爲標杆,用k保存 , 
若標杆值比右邊數組值大,則交換兩值,此時交換隻需將右邊的值賦給標杆所在位置,
標杆值由k記錄,不需要記錄。同理可知標杆值比左邊數小。
一趟比較完之後記得將k值返還給a[l]。 
*/
//qSort(a,0,n-1);
/*
第二種: 調用庫函數快排 
只需編寫comp()比較函數即可 
*/ 
qsort(a,n,sizeof(a[0]),comp);//調用庫函數快排 
for(int i = 0; i < n; i++){
printf("%d ",a[i]);
}
printf("\n");
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章