1. 程式人生 > >分治法之快速排序演算法解題思路

分治法之快速排序演算法解題思路

快速排序演算法的基本思想是:先找一個基準元素(比如待排序陣列的第一個元素),進行一趟快速排序,使得該基準元素左邊的所有資料都它小,而右邊的所有資料都它大,然後再按此方法,對左右兩邊的資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個陣列變成有序序列

比如我們現在對序列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;
}