1. 程式人生 > >可能是你最容易看明白的快速排序(C++實現)

可能是你最容易看明白的快速排序(C++實現)

我認為現在CSDN大多關於快速排序的程式都是在扯淡。

不是針對某一位,我是說,我看到CSDN的C++快排程式都是扯淡。

他們根本沒有把重點放在快速排序本身,為什麼我這麼說?我們往下看。

快排的本質思想就是分而治之。

舉例說明,我們要對3 5 2 1 4進行排序。

首先我們選中一個數字當做是pivot,就是支點啦,然後我們把所有比pivot小的都放在左邊,比他大的放在右邊。我們這裡把數字2當做pivot。

(1) 2 (3 5 4)

ok,就變成了這樣,下面我們要怎麼樣?我們只要對(1)這一部分和(3 5 4)這一部分再用相同的方法排序不就好了?

注意,原來(3 5 2 1 4)是五個數,現在變成了兩部分+支點,這就是分而治之的典型思想。

如果用python非常好寫,但是我們要用C++就會發生一些問題。不信的話,我們順著C++的思路向下想——

第一步,我們寫個函式叫quicksort,然後想一下,這個遞迴函式的基線條件是什麼?你考慮一下。我們是不是可以用雙指標,一個指向排序的頭部,一個指向排序的尾部,當頭部超過尾部的時候,說明待排序的陣列小於等於1了,此時肯定是有序的。廢話,[1]這不是有序的嗎?一個數字當然有序啊。

第二步,我們找一個pivot,這個簡單,雙指標/2,二分法的經典做法就行。

第三步,我們把所有比pivot小的都放在前面,大的都放在後面(注意,我在程式裡pivot指的是下標,我在文中直接指的是數字大小,在程式中應該是array[pivot])。就是這一步啊,現在大家的程式碼都著重於寫這玩意兒,這才是你們看的其他人寫的快排的時候,理解最困難的地方!

第三步(新),那我就用最簡單的辦法,新建兩個陣列,less陣列放小的,great陣列放大的,一個int叫tmp放pivot。

第四步,把less,tmp和great連線起來。這就是新的data,然後帶著新的data和雙指標去遞迴吧!

#include "iostream"
#include "vector"
#include "algorithm"
using namespace std;
//c++實現快速排序
void quicksort(vector<int> &data, int left,int right)
{
	if (left >= right)
		return;
	int pivot = (left+right)/2;
	vector<int> less;
	vector<int> greater;
	int tmp;
	for (int i = left; i < right; i++)
	{
		if (i == pivot)
			tmp = data[pivot];
		else if (data[i] < data[pivot])
			less.push_back(data[i]);
		else
			greater.push_back(data[i]);
	}
	for (int i = left; i < right; i++)
	{
		if (i < left + less.size())
			data[i] = less[less.size() - i - 1 + left];
		else if (i == left + less.size())
			data[i] = tmp, pivot = i;
		else
			data[i] = greater[greater.size() - i+ less.size() + left];
	}
	quicksort(data,left, pivot);
	quicksort(data, pivot+1,right);

	
}


int main() 
{
	vector<int> data = { 12, 4, 34, 6, 8, 65, 3, 2, 988, 45 };
	cout << "排序前:";
	for each (auto var in data)
	{
		cout << var << "  ";
	}
	cout << endl;
	quicksort(data, 0, data.size());
	cout << "排序後:";
	for each (auto var in data)
	{
		cout << var << "  " ;
	}
	
	
	while (1);
	return 0;

}