快速排序(解釋+程序模板)

首先,假設有一個原始雜亂的數列,權值爲 : 3、1、3、6、4、0  。

首先在這個有6個值的數列,先選取一個基準數,這個基準數選法不唯一。

(我們這裏的基準數選擇數列的第一個就好,其他原理也相同,算法程序略不同)。

  1. 初始基準數: 3
  2. L和R表示當前數列的第一個元素的位置,最後一個元素的位置。
  3. 圖中有兩個指針分別寫着左和右,初始時指向數列的 L-1 和 R+1的位置。

快排的基本做法:

第一趟-移動左指針:

移動左指針,當遇到第一個不小於基準數的數,那麼停止。到3成立,所以停止。

 

第一趟-移動右指針:

移動右指針,當遇到第一個不大於基準數的數,那麼停止。這裏,到0這已經成立。

 

第一趟交換:交換

然後此時:如果左指針在右指針的左邊,那麼交換 3 和 0。如果不在,會有另外的選擇。

 

第二趟-移動左右指針:

和第一趟是同理的,移動完畢後的結果如圖。

第二趟-是否交換?

此時發現右指針在左指針左側了,不符合了左指針在右指針的左邊的條件,所以不交換。

此時的操作:把這個大數列分成兩個小數列,從L到右指針所有的數作爲一個新數列A,從左指針到R的數作爲一個新的數列B。

新的數列A:

新數列B:

分治:A和B遵從同樣的規則。

注意!此時的基準數,是A和B各自的基準數了,新的基準數。A的基準數:0  B的基準數:6。

 

以數組A爲例A,流程:

移動指針,分別到數值爲0的位置----》並且此時符合交換條件,左指針在左,那麼交換0、0,所以沒什麼大變化。

繼續移動指針。右指針跑到了更左邊的位置。我們需要對A繼續分治。

 

根據指針位置,分出新的分組:A1、A2

 

此時A1就剩一個元素了,那麼我們就不管他了

A2還需要最後的移動,A2的基準值:1

左指針在更左邊,進行交換。得到最後的A2數列: 0 、1

A = A1 + A2 = { 0、0、1}

B = {3、4、6}

總數列 = A + B = {0、0、1、3、4、6}

 

總結:快排幾個重要的點

  1. 基準值的選取
  2. 移動指針
  3. 是否交換?
  4. 分治

下面給出快排模板:

#include<iostream> 

using namespace std;

const int N = 1e6 + 10;

int n;
int q[N];

void quick_sort(int q[], int l, int r)
{
	if(l >= r ) return ;//如果到頭了就停止 

	int x = q[l], i = l -1, j = r + 1;
		
	while(i<j)
	{
		do i++; while(q[i] < x);
		do j--; while(q[j] > x);
		if(i < j) swap(q[i],q[j]);
	} 	
	quick_sort(q,l,j);
	quick_sort(q,j+1,r);
	
}

int main()
{
	scanf("%d", &n);	
	
	for (int i = 0; i < n; ++i ) scanf("%d",&q[i]);
	
	quick_sort(q, 0, n-1);
	
	for (int i=0; i < n; ++ i) printf("%d ",q[i]);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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