快速排序算法的c++實現


很早以前看過快排算法覺得自己掌握了,,課今天用的時候發現老出錯,認真想想發現自己一直搞錯了。。。

下面先說一下我的想法:

首先,快排的思想就是

  1. 從數列中挑出一個元素,稱為 "基准"(pivot),
  2. 重新排序數列,所有元素比基准值小的擺放在基准前面,所有元素比基准值大的擺在基准的后面(相同的數可以到任一邊)。在這個分區退出之后,該基准就處於數列的中間位置。這個稱為分區(partition)操作。
  3. 遞歸地(recursive)把小於基准值元素的子數列和大於基准值元素的子數列排序

那么這里需要考慮的就是如何進行分區,這個是最重要的,先來看看我的分區的實現:(這里的provit我就不用隨機數來實現了,直接選第一個)

int partition(int array[], int begin, int end) {
	int index = begin;
	int proviet = array[begin];
	swap(array[index], array[end]);//將provit換到最后
	for(int i = begin; i != end; i++) {//將小於provit的元素放到左邊,大的放到右邊
		if (array[i] < proviet)
			swap(array[index++], array[i]);
	}
	swap(array[index], array[end]);

	return index;
}

  首先,將provit移到數組的最后一位,這樣在數組分區的時候就不會影響到provit,也就是這句

swap(array[index], array[end]);

假設我們要分區的數組是6 7 4 3 56 5, 那么到現在數組應該變成這樣了 

然后,就要將除 provit 意外的全部元素進行遍歷,此時 index 是 0,i 也從 0 開始。那么因為第一個 5 < 6,所以變成這樣

到第三步,因為7>6, 所以 index 沒變,而 i 自增,即這樣,那么此時因為 4 < 6, 所以將 4 和 7 交換,變成這樣

下面的一招這個原理即可。那么,到 for 循環完成后,數組變成如下:,這時,因為 index 位的數大於等於 privot, 所以將他們交換,最后達到的效果就是大的全在右邊,小的全在左邊。

然后是 quickSort()的內容:

void quickSort(int array[], int begin, int end) {
	if (begin >= end)
		return;
	int position = partition(array, begin, end);
	quickSort(array, begin, position - 1);
	quickSort(array, position + 1, end);	
}

  這里就是用遞歸的方法將數列分段進行大小分區,這個應該不難理解。因為每一段內部的元素的都比他后面段的所有元素都小,那么排出來的就應該是一個有序列了。

對於provit的選擇,其實沒有太多的要求,只是說你用隨機數來產生的話更可能得到一個好的 provit 使得分區更好得到更好的速度。因為使用隨機數法使得輸入數據的次序對算法不產生影響。只有在隨機數產生器給出了一個很不巧的排列時,隨機化算法的最壞情況性態才會出現。事實上可以證明幾乎所有的排列都可使快速排序接近平均情況性態,只有非常少的幾個排列才會導致算法的近最壞情況性態。所以一般情況下采用隨機數法。

如果你想用隨機數來實現,可以看看這個http://code.wikia.com/wiki/Random_number


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM