重温数据结构,顺手写下几种常用的排序算法,以备查询。 #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <malloc.h> #include <memory.h> #include <time.h> void print(int a[], int n) { int i = 1; while(i<=n) { printf("%d,", a[i]); i++; } printf("/n"); return; } //直接插入排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序 //a[0]不参与排序,实际排序空间为a[1]~a[n] void InsertSort(int a[], int n) { for(int i=2; i<=n; i++) { if(a[i]<a[i-1]) { a[0] = a[i]; int j = i - 1; //扫描有序空间, while(a[0]<a[j]) { a[j+1] = a[j]; j--; } a[j+1] = a[0]; } } printf("InsertSort : "); print(a, n); return; } //一次Shell排序过程 void ShellPass(int a[], int n, int increment) { for(int i=increment+1; i<=n; i++) { if(a[i]<a[i-increment]) { a[0] = a[i]; int j=i-increment; while(j>0 && a[0]<a[j]) { a[j+increment] = a[j]; j -= increment; } a[j+increment] = a[0]; } } return; } //Shell排序,时间复杂度依赖于增量序列,应避免互为倍数的增量序列, //目前较好时间复杂度为n^1.25~1.6n^1.25,空间复杂度为O(1),不稳定排序 void ShellSort(int a[], int n) { int increment = 20; do { increment = increment/3 + 1; ShellPass(a, n, increment); }while(increment>1); printf("ShellSort : "); print(a, n); return; } //冒泡排序,时间复杂度O(n^2),空间复杂度O(1),稳定排序 void BubbleSort(int a[], int n) { for(int i=1; i<n; ) { int lastExchangePos = n;//记录一次排序中最后一次交换的位置,此位置之前的所有数据都已有序 for(int j=n-1; j>=i; j--) { if(a[j+1]<a[j]) { a[0] = a[j+1]; a[j+1] = a[j]; a[j] = a[0]; lastExchangePos = j+1; } } i = lastExchangePos; } printf("BubbleSort : "); print(a, n); return; } 快速排序,平均时间复杂度为O(nlgn),空间复杂度为O(lgn)~O(n),快速排序不稳定。 //C++中快速排序的实现, void QuickSort(int a[], int low, int high) { srand(time(0)); a[0] = a[rand()%(high-low+1)+low];//随机选择基准,改善快排的性能 int tmp = 0; int i = low, j = high; while(i<=j) { while(i<high && a[i]<a[0]) i++; while(j>low && a[j]>a[0]) j--; if(i<=j) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; i++; j--; } } if(j>low) QuickSort(a, low, j); if(i<high) QuickSort(a, i, high); return; } //快速排序的一次划分 int Partition(int a[], int low, int high) { srand(time(0)); int pos = rand()%(high-low+1)+low; a[0] = a[pos]; a[pos] = a[low]; while(low<high) { while(low<high && a[0]<a[high]) high--; if(low<high) a[low++] = a[high]; while(low<high && a[0]>a[low]) low++; if(low<high) a[high--] = a[low]; } a[low] = a[0]; return low; } //数据结构中标准的快速排序算法 void QSort(int a[], int low, int high) { if(low<high) { int p = Partition(a, low, high); QSort(a, low, p-1); QSort(a, p+1, high); } return; } //直接选择排序,时间复杂度为O(n^2),空间复杂度为O(1),不稳定排序 void SelectSort(int a[], int n) { for(int i=1; i<=n; i++) { int min = i; for(int j=i+1; j<=n; j++) { if(a[j]<a[min]) min = j; } if(min!=i) { a[0] = a[i]; a[i] = a[min]; a[min] = a[0]; } } printf("SelectSort : "); print(a, n); return; } //调整堆 void Heapify(int a[], int s, int to) { /* //Heapify方法的递归算法 a[0] = a[s]; int tmp = 2*s; if(tmp+1<=to && a[tmp]<a[tmp+1])tmp++; if(tmp<=to && a[0]<a[tmp]) { a[s] = a[tmp]; a[tmp] = a[0]; Heapify(a, tmp, to); }*/ //Heapify方法的递推算法 a[0] = a[s]; for(int j=2*s; j<=to; j*=2) { if(j+1<=to && a[j]<a[j+1])j++; if(j<=to && a[0]>=a[j]) break; a[s] = a[j]; // a[j] = a[0]; s = j; } a[s] = a[0]; return; } //堆排序,最坏时间复杂度nlgn,空间复杂度为O(1),不稳定排序,适合大量数据的排序 void HeapSort(int a[], int n) { for(int j=n/2; j>0; j--) Heapify(a, j, n); for(int j=n; j>1; j--) { a[0] = a[j]; a[j] = a[1]; a[1] = a[0]; Heapify(a, 1, j-1); } printf("HeapSort : "); print(a, n); return; } //归并排序的一次合并过程 void MergePass(int a[], int low, int mid, int high) { int *p = (int*)malloc(sizeof(int)*(high-low+1)); assert(p!=NULL); int *pi = p; int i = low, j = mid+1; while(i<=mid && j<=high) *(pi++) = (a[i]<=a[j])? a[i++] : a[j++]; while(i<=mid) *(pi++) = a[i++]; while(j<=high) *(pi++) = a[j++]; pi = p; while(low<=high) a[low++] = *(pi++); free(p); return; } //归并排序,时间复杂度O(nlgn),空间复杂度O(n),稳定排序 void MergeSort(int a[], int low, int high) { if(low<high) { int mid = (low+high)/2; MergeSort(a, low, mid); MergeSort(a, mid+1, high); MergePass(a, low, mid, high); } return; } int main() { //source[0]不参与排序,做为辅助空间使用 int source[] = {0, 10, 8, 30, 55, 6, 0, 99, 87, -5, 32, 66, 54, 33, 21, 32, 96, 121, 70}; int n = sizeof(source)/sizeof(source[0])-1; int a[sizeof(source)/sizeof(source[0])]; memcpy(a, source, sizeof(source)); InsertSort(a, n); memcpy(a, source, sizeof(source)); ShellSort(a, n); memcpy(a, source, sizeof(source)); BubbleSort(a, n); memcpy(a, source, sizeof(source)); QuickSort(a, 1, n); printf("QuickSort : "); print(a, n); memcpy(a, source, sizeof(source)); QSort(a, 1, n); printf("QSort : "); print(a, n); memcpy(a, source, sizeof(source)); SelectSort(a, n); memcpy(a, source, sizeof(source)); HeapSort(a, n); memcpy(a, source, sizeof(source)); MergeSort(a, 1, n); printf("MergeSort : "); print(a, n); system("pause"); return 0; }