1.O(n^2)排序算法
1.冒泡排序:稳定
int* bubbleSort1(int* A, int n) { int k=0;//last sink position for(int i=n-1;i>0;i=k){ k=0; for(int j=0;j<i;j++){ if(A[j]>A[j+1]){ int temp=A[j]; A[j]=A[j+1]; A[j+1]=temp; k=j; } } } return A;
}
2.选择排序:不稳定
int* selectionSort(int* A, int n) { // write code here
for(int i=0;i<n-1;i++){ int min=A[i]; int minJ; for(int j=i+1;j<n;j++) if(min>A[j]){ min=A[j];minJ=j; } if(min!=A[i]){ A[minJ]=A[i]; A[i]=min; } } return A; }
3.插入排序
int* insertionSort(int* A, int n) { for(int i=1;i<n;i++){ int key=A[i]; int j; for(j=i-1;j>=0&&key<A[j];j--) A[j+1]=A[j]; A[j+1]=key; } return A; }
2.O(N*logN)排序算法
1.归并排序
void merge1(int* A,int p,int q,int r) { int MAX=2147483647; int arr1[q-p+2]; int arr2[r-q+1]; for(int i=p;i<=q;i++) arr1[i-p]=A[i]; arr1[q-p+1]=MAX; for(int i=q+1;i<=r;i++) arr2[i-q-1]=A[i]; arr2[r-q]=MAX; int i1=0,i2=0; for(int i=p;i<=r;i++){ if(arr1[i1]<=arr2[i2]) A[i]=arr1[i1++]; else A[i]=arr2[i2++]; } } int* mergeSort1(int* A,int p,int r){ if(p<r){ int q=(p+r)/2; mergeSort1(A,p,q); mergeSort1(A,q+1,r); merge1(A,p,q,r); } return A; }
2.快速排序
void exchange(int* a1,int* a2){ int temp=*a1; *a1=*a2; *a2=temp; } int partition(int* A,int p,int r){ int key=A[r]; int i=p-1; for(int j=p;j<r;j++){ if(A[j]<key){ i++; exchange(A+j,A+i); } } exchange(A+i+1,A+r); return i+1; } int* quickSort1(int* A,int p,int r){ if(p<r){ int q=partition(A,p,r); quickSort1(A,p,q-1); quickSort1(A,q+1,r); } return A; } int* quickSort(int* A, int n) { // write code here return quickSort1(A,0,n-1); }
3.shell排序
int* shellSort(int* A, int n) { // write code here for(int h=n/2;h>0;h/=2){ for(int i=h;i<n;i++){ int key=A[i]; int j; for(j=i-h;j>=0&&key<A[j];j-=h){ A[j+h]=A[j]; } A[j+h]=key; } } return A; }
4.堆排序
void swap(int *a,int* b){ int temp=*b; *b=*a; *a=temp; } void percDown(int* A,int i,int N){ int parent,child; int key=A[i]; for(parent=i;parent*2+1<N;parent=child){ child=parent*2+1; if((child!=N-1)&&(A[child]<A[child+1])) child++; if(key>=A[child]) break; else A[parent]=A[child]; } A[parent]=key; }
// S(n)=O(1) int* heapSort(int* A, int n) { // write code here //从最后一个父节点向上建堆 for(int i=n/2-1;i>=0;i--) percDown(A,i,n); for(int i=n-1;i>0;i--){ swap(A,A+i); percDown(A,0,i); } return A; } }
3.空间复杂度分析
O(1):冒泡排序,选择排序,插入排序,希尔排序,堆排序
O(n):归并排序
不确定:快速排序,与基准的选择和划分实现有关。
4.排序算法的稳定性
稳定性:指相同的元素在排序后其先后顺序不变。
稳定算法:冒泡,插入,归并,计数,基数,桶排序
不稳定算法:选择,快速,希尔,堆排序
5.关于快速排序的说明
快速排序并不一定比归并和堆排序优良,在最好情况下,他们的复杂度相同,只是快排的常量系数较小。
6.工程上的排序
1.工程上使用综合排序
2.数组小时,一般会使用常量系数低的插入排序
3.数组较大时,考虑快排等N*logN排序。