C++ 競賽排序

_Gion發表於2017-08-16

(一)選擇排序

選擇排序:每一趟選一個最小(大)值並固定

#include <iostream>
using namespace std;

int a[1001];
int n, temp;

int main() {
	cin >> n;
	for(int i=0; i<n; i++) cin >> a[i];
	for(int i=0; i<n-1; i++) {
		for(int j=i+1; j<n; j++) {
			if(a[i] > a[j]) {
				temp = a[i];
				a[i] = a[j];
				a[j] = temp;
			}
		}
	}
	for(int i=0; i<n; i++) cout << a[i] << " "; 
	return 0;
}

時間複雜度:O(n²)

(二)氣泡排序

氣泡排序:n個數,每次將相鄰的兩兩比較、交換(冒泡),做n次(實際做n-1次就已排序完)

#include <iostream>
using namespace std;

int a[1001];
int n, temp;

int main() {
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	for(int i=1; i<=n-1; i++) {
		for(int j=1; j<=n-i; j++) {            //n-i:每次排序一次,最後i個位置是固定的因此不需要再次排序 
			if(a[j] > a[j+1]){
				temp = a[j+1];
				a[j+1] = a[j];
				a[j] = temp;
			}
		}
	}
	for(int i=1; i<=n; i++) cout << a[i] << " ";
	return 0;
}



時間複雜度:O(n²)



(三)桶排序

在已知資料為正整數和有限範圍時,可以用桶排序
#include <iostream>
using namespace std;

#define LEN 1001

int b[LEN];
int n, tmp;

int main() {
	cin >> n;
	for(int i=1; i<=n; i++) {
		cin >> tmp;
		b[tmp] ++;
	}
	for(int i=0; i<LEN; i++)
		for(int j=0; j<b[i]; j++)
			cout << i << " ";
	return 0;
}

(四)快速排序

快速排序:每次將資料分成兩部分,左邊部分中的元素一定比右邊部分的元素小,然後將這兩部分接著快速排序(遞迴)

#include <iostream>
using namespace std;

int a[1001];
int n;

void qsort(int, int);

int main() {
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	qsort(1, n);
	for(int i=1; i<=n; i++) cout << a[i] << " ";
	cout << endl;
	return 0;
}

void qsort(int l, int r) {
	int i, j, mid, tmp;
	i = l;
	j = r;
	mid = a[(l+r)/2];
	do {
		while(a[i] < mid) i ++;
		while(a[j] > mid) j --;
		if(i <= j) {
			tmp = a[i];
			a[i] = a[j];
			a[j] = tmp;
			i ++;
			j --;
		}
	} while(i <= j);
	if(l < j) qsort(l, j);
	if(i < r) qsort(i, r);
}



時間複雜度:O(nlog2n)

(五)插入排序

插入排序:一種簡單排序

開始陣列a的有序區為a[1]

a[2]加入有序區,找到合適位置插入,有序區域擴大為a[1~2]

...

最後a[1~n]為有序區


#include <iostream>
using namespace std;

int n;
int a[1001];

int main() {
	int j, tmp;
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	for(int i=2; i<=n; i++) {
		j=i-1;
		tmp = a[i]; 
		while(tmp < a[j]) a[j+1] = a[j --];     //後移 
		a[j+1] = tmp;                           //插入 
	}
	for(int i=1; i<=n; i++) cout << a[i] << " ";
	cout << endl;
	return 0;
}


時間複雜度:O(n²)

Shell排序

希爾(Shell)排序是基於插入排序的分組排序

 

排序過程:

1 先取一個正整數d1(d1<n)作為第一個增量,將全部n個記錄分成d1組,把所有相隔d1資料放在一組中,即a[k], a[d1+k], a[2*d1+k] , …分在同一組中,在各組內進行直接插入排序。這樣一次分組並排序即為一趟希爾排序;

2 d2 < d1 , 繼續分組..

 

(由於增量d不是明確的,因此Shell排序有很多演算法實現,如Knuth, Pratt, Gonnet等)

 

這裡介紹最初的演算法:增量每次除以2


#include <iostream>
using namespace std;

void Shell_Sort(int a[], int n) {
	int temp;
	for (int gap = n/2; gap > 0; gap /= 2) {   //gap為增量
		for (int i = gap; i<=n; i++) {
			for (int j = i-gap; j >= 1; j -= gap) {
				if(a[j] > a[j + gap]) {
					temp = a[j];
					a[j] = a[j + gap];
					a[j + gap] = temp;
				}
			}
		}
	}
}

int a[10001];
int n;

int main() {
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	Shell_Sort(a, n);
	for(int i=1; i<=n; i++) cout << a[i] << ' ';
	cout << endl;
	return 0;
}


(未完)


相關文章