分治法之快速排序演算法解題思路
快速排序演算法的基本思想是:先找一個基準元素(比如待排序陣列的第一個元素),進行一趟快速排序,使得該基準元素左邊的所有資料都它小,而右邊的所有資料都它大,然後再按此方法,對左右兩邊的資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個陣列變成有序序列。
比如我們現在對序列arr={-2,6,88,0,-4,56}這6個數進行排序:
0 | 1 | 2 | 3 | 4 | 5 |
-2 | 6 | 88 | 0 | -4 | 56 |
初始時待排序序列是整個序列,故首個元素為arr[0],首先選基準元素 key=arr[0]即-2,變數i指向當前序列首個下標,j指向最後一個下標的下一個下標,即:i=0; j=6;
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-2 | 6 | 88 | 0 | -4 | 56 | |
i | j |
無論是對於變數i還是j,我們都是先移動再判斷是否繼續移動。首先++i,即向右移動i,直到它已經移到待排序序列最右邊即i=5處,或者arr[i] >= key時,停止移動。比如這裡i在向右移動,然後它發現移到下標1的時候,對應元素的值為6,大於-2,故i停止移動:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-2 | 6 | 88 | 0 | -4 | 56 | |
i | j |
接下來移動j了:它會向左移,直到它找到一個數,使得arr[i]<=key,這裡j發現移到下標4的時候,對應元素為-4,小於key,故停止移動:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-2 | 6 | 88 | 0 | -4 | 56 | |
i | j |
此時判斷一下i和j有沒有碰頭,如果i>=j,終止迴圈,否則,交換arr[i]和arr[j],然後繼續跟上面一樣移動 i j 直到它們碰頭:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-2 | -4 | 88 | 0 | 6 | 56 | |
i | j |
這一次i和j碰頭(i>=j)了,所以迴圈終止:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-2 | -4 | 88 | 0 | 6 | 56 | |
j | i |
交換arr[p]與arr[j]位置的元素,arr[p]就是當前序列的首個元素-2,交換結果如下:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-4 | -2 | 88 | 0 | 6 | 56 | |
j | i |
至此第一趟快速排序結束了,我們可以發現,到目前為止,基準元素-2現在在下標 j=1 那裡,而它左邊的每一個元素{-4}都比它小,而右邊的每一個元素{88,0,6,56}都比它大,當然,被分隔出來的這兩個序列目前還是無序的,所以我們接下來的任務就是分別對這兩個序列進行快速排序,如此遞迴下去,直到整個陣列成為一個有序序列:
由於左邊序列{-4}只有一個元素了,那就不用排序了,所以輪到右邊序列{88,0,6,56}排序:
當前待排序序列為{88,0,6,56}了,同樣選基準元素key=88,i指向88對應的位置,j指向當前序列最後一個元素的下一個位置6:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-4 | -2 | 88 | 0 | 6 | 56 | |
i | j |
然後又是跟之前一樣的方式將這個序列排成{56,0,6,88}:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-4 | -2 | 88 | 0 | 6 | 56 | |
i j |
0 | 1 | 2 | 3 | 4 | 5 | 6 |
-4 | -2 | 56 | 0 | 6 | 88 | |
i j |
然後,我們又完成了一趟快速排序,接下來的任務,就是對基準元素88左右兩個序列繼續排對吧?,也就是對{56,0,6}繼續排,因為88右邊沒有元素了,所以它右邊就不需要遞迴了......
排序全過程加最終結果:
原始序列:arr[]={-2,6,88,0,-4,56}
好了,思路介紹到這,又是原始碼了,還是那句話,若有問題,歡迎各位小夥伴指出哈:
#include <iostream>
using namespace std;
void swap(int i,int j,int arr[])
{
int t;
t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
void quicksort(int p,int q,int arr[])
{
if(p>=q)return;
int i=p,j=q+1,key=arr[p];
while(1)
{
while(arr[++i]<key && i<q);
while(arr[--j]>key);
if(j<=i)
break;
swap(i,j,arr);
}
arr[p]=arr[j];
arr[j]=key;
quicksort(p,j-1,arr);
quicksort(j+1,q,arr);
}
int main()
{
int arr[]= {-2,6,88,0,-4,56};
quicksort(0,5,arr);
for(int i=0; i<6; i++)
{
cout << arr[i] << " ";
}
cout << endl;
system("pause");
return 0;
}