冒泡--选择--插入--希尔排序

来源:互联网 发布:阿里云修改dns 编辑:程序博客网 时间:2024/05/21 07:00
#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];elsebreak;}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;}

原创粉丝点击