冒泡--選擇--插入--希爾排序
阿新 • • 發佈:2019-01-04
#include <cstdlib> #include <iostream> #include <ctime> using namespace std; template <typename T> void print(const T *A, int n) { for(int i=0; i<n; i++) cout << A[i] << " "; cout << endl; } template<typename T> void swapN(T &a, T &b) { T tmp = a; a = b; b = tmp; } // 氣泡排序: 每次迴圈總是將最大元素移到隊尾: O(n^2),穩定的排序演算法 template<typename T> void bubbleSort(T *A, int n) { for(int i=0; i<n-1; i++) { for(int j=0; j<n-i-1; j++) { if(A[j] > A[j+1]) { swapN(A[j],A[j+1]); } } } } // 雞尾酒排序:氣泡排序的改進,第一輪,從小到大,第二輪,從大到小,迴圈: O(n^2) template<typename T> void cocktailSort(T *A, int n) { int left=0; int right = n-1; while(left<right) { for(int i=left; i<right; i++) { if(A[i] > A[i+1]) swapN(A[i],A[i+1]); } right--; for(int i=right; i>left; i--) { if(A[i] < A[i-1]) swapN(A[i],A[i-1]); } left++; } } // 選擇排序:每次從剩餘的元素中找出最大的元素與隊尾元素交換: O(n^2), 不穩定的排序演算法 template <typename T> void selectSort(T *A, int n) { for(int i=0; i<n-1; i++) { int min=i; for(int j=i+1; j<n; j++) { if(A[j]<A[min]) min = j; } if( min!= i) swapN(A[min],A[i]); } } // 插入排序: 左手持牌,右手的牌倒序遍歷插入, O(n^2), 最好情況能到O(n) template<typename T> void insertSort(T *A, int n) { for(int i=1; i<n; i++) { T cur = A[i]; int j; for(j=i-1; j>=0; j--) { if(A[j] > cur) { A[j+1] = A[j]; // 後移操作。。。 }else { break; } } A[j+1] = cur; // 找到要插入的位置進行插入 } } // 希爾排序:插入排序的一種高效改進,按間隔h一次執行插入排序,使得原始陣列變得越來越有序, // h逐漸遞減到1,變成正常的插入排序,插入排序對於大部分有序的數列更有效: 不穩定的排序: O(nlogn)~O(n^2) template<typename T> void shellSort(T *A, int n) { int h=0; while( h<=n ) { h = 3*h + 1; // 生成間隔h } while( h>=1 ) { // 完成間隔為 h 子序列的插入排序 for(int i=h; i<n; i+=h) { T cur = A[i]; int j; for(j = i-h; j>=0; j-=h) { if(A[j]>cur) A[j+h] = A[j]; else break; } A[j+h] = cur; } h = (h-1)/3; // 遞減間隔 } } int main() { int n; while(cin>>n) { int *A = new int[n]; srand(time(NULL)); for(int i=0; i<n; i++) A[i] = rand()%100; print(A,n); //bubbleSort(A,n); //cocktailSort(A,n); //selectSort(A,n); //insertSort(A,n); shellSort(A,n); print(A,n); delete[] A; } return 0; }