【演算法】快速排序

默默無聞的鹹魚發表於2021-01-01

快排思想:
1.隨便找一個基準值key(一般是陣列的第一個數)把比它小的數都放到前面,比它大的數都放到後面。
2.得到key前後的兩個小陣列,對兩個陣列分別再次排序,重複1步驟。
3.如此遞迴呼叫,直到排序完成。

步驟1有很多可能的實現,殊途同歸,列舉兩種:
1.把基準值前後的元素分別提取出來作為陣列a,b,對a,b分別呼叫排序函式。c++可能得用到STL容器。容易理解但是空間佔用偏大。python可以用list。

2.通過三個重要變數:
key:int。儲存基準值。
high:int。開始時指向陣列的最後一個數。
low:int。開始時指向最陣列的第一個數。

  1. high依次向前挪動,若找到小於key的值,就與low交換。此時low指向的陣列的值恰恰是key,交換之後,high的位置變成了key,low的位置變成了比key小的值。
  2. 接著是low向前挪動,若找到大於key的值,就與high交換。此時high指向的值是key,交換之後low的值是key,high的位置是比key大的值。
  3. 再依次挪動high,low和交換… 直到high與low相等,假設為mid。此時key的兩邊分別是小於key的值和大於key的值。mid恰好指向key。
  4. 遞迴呼叫。直到最小的陣列都是有序的。

注:只有從high開始,才能讓最後的mid指向key。




#include <iostream>
using namespace std;
int* a;//定義全域性變數來避免傳陣列(懶人操作)
void qsort(int high, int low);
int main() {
	int n=0,low=0,high=0;
	cin >> n;
	a = new int[n] {};
	for (int i = 0;i < n;i++) {
		cin >> a[i];
	}
	low = 0;
	high = n - 1;
	qsort(low, high);
	for (int i = 0;i < n;i++) {
		cout << a[i] << " ";
	}
	cout << endl;
}
void qsort(int low, int high) {
	int key = 0, temp = 0, n = 0;
	n = high;  //n用來存陣列大小遞迴時要用到
	key = a[low];
	if (high == low) {
		return;
	}
	while (high > low) {
		//從後往前找到第一個小於key的數
		while (a[high] >= key&&high>low) {//這裡要加條件high>low 否則可能以為移動過多出錯
			high--;
		}
		//把找到的a[high]與a[low]交換
		if (high > low) {
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;
		}
		//從前往後找到第一個大於key的數
		while (a[low] <= key&&high>low) {
			low++;
		}
		//把找到的a[low]與a[high]交換
		if (high > low) {
			temp = a[high];
			a[high] = a[low];
			a[low] = temp;
		}
		qsort(0, low - 1);
		qsort(low + 1, n);
	}
}

相關文章