1、快速排序
通过选择轴值,一次划分都能确定该轴值得位置,其时间复杂度最好的情况(每次划分都恰好将区间平分为等长的两半)下为Ο(nlgn),最差情况(每次划分将区间分成0与n-1)为O(n^2)。其空间复杂度考虑递归的栈深为O(lgn)。
1 /************************************************************************* 2 **File Name :quicksort.c 3 **Author : 4 **Contact : 5 **Created Time :Mon 12 May 2014 02:12:57 PM CST 6 **Brief : 7 **Development note : 8 ************************************************************************/ 9 10 /********************************include*********************************/ 11 #include<stdio.h> 12 13 int partition(int a[],int start,int end) 14 { 15 int i,j,tmp; 16 i = start; 17 j = end; 18 while(i < j){ 19 while(a[i] < a[j] && i < j){ 20 j--; 21 } 22 if(i < j){ 23 tmp = a[i]; 24 a[i] = a[j]; 25 a[j] = tmp; 26 i++; 27 } 28 while(a[i] < a[j] && i < j){ 29 i++; 30 } 31 if(i < j){ 32 tmp = a[i]; 33 a[i] = a[j]; 34 a[j] = tmp; 35 j--; 36 } 37 } 38 return i; 39 } 40 int quicksort(int a[],int start,int end) 41 { 42 if(start >= end) 43 return 0; 44 int mid; 45 mid = partition(a,start,end); 46 quicksort(a,start,mid-1); 47 quicksort(a,mid+1,end); 48 }
2、堆排序
堆排序通过堆顶的对换和堆的不断调整实现。其时间复杂度为O(nlgn),与初始序列无关。
1 /************************************************************************* 2 **File Name :heapsort.c 3 **Author : 4 **Contact :shixuyong@scit.ac.cn 5 **Created Time :Mon 12 May 2014 02:40:23 PM CST 6 **Brief : 7 **Development note : 8 ************************************************************************/ 9 /* 10 *澶ф牴鍫*鏁扮粍浠寮€濮*/ 11 /********************************include*********************************/ 12 #include<stdio.h> 13 void sift(int a[],int k,int m) 14 { 15 int i = 2*k,tmp; 16 /* 17 * 璋冩暣浜唅 = 2*i鐨勪綅缃紝鏀惧埌寰幆鐨勬渶鍚庛€傚惁鍒欏嚭閿欍€ * */ 18 while(i <= m){ 19 if(a[i] < a[i+1]&& i+1 <= m) 20 i = i+1; 21 if(a[i] > a[k]){ 22 a[0] = a[i]; 23 a[i] = a[k]; 24 a[k] = a[0]; 25 k = i; 26 i = 2*i; 27 } 28 else 29 break; 30 } 31 } 32 void heapsort(int a[],int m) 33 { 34 int i,tmp,j=0; 35 for(i = m/2; i > 0; i--){ 36 sift(a,i,m); 37 } 38 for(i = 1;i < m; i++){ 39 a[0] = a[1]; 40 a[1] = a[m-i+1]; 41 a[m-i+1] = a[0]; 42 sift(a,1,m-i); 43 } 44 }
3、归并排序
归并的思想在于,每次合并两个相邻的一排序的序列,多次归并实现排序。其时间复杂度为O(nlgn)与初始序列无关,空间复杂度为O(n) 。
1 /************************************************************************* 2 **File Name :mergesort.c 3 **Author :Shi Xuyong 4 **Contact :shixuyong@scit.ac.cn 5 **Created Time :Mon 12 May 2014 08:23:27 PM CST 6 **Brief : 7 **Development note : 8 ************************************************************************/ 9 10 /********************************include*********************************/ 11 #include<stdio.h> 12 /* 13 */ 14 void merge(int a[],int b[],int s,int m,int t) 15 { 16 int i,j,k; 17 i = s; 18 j = m+1; 19 k = i; 20 while(i <= m && j <= t){ 21 if(a[i] < a[j]){ 22 b[k++] = a[i++]; 23 } 24 else{ 25 b[k++] = a[j++]; 26 } 27 } 28 if(j <= t){ 29 while(j <= t ){ 30 b[k++] = a[j++]; 31 } 32 } 33 else{ 34 while(i <= m){ 35 b[k++] = a[i++]; 36 } 37 } 38 } 39 void mergepass(int a[],int b[],int n,int h) 40 { 41 int i = 1; 42 while(i <= n-2*h+1){ 43 merge(a,b,i,i+h-1,i+2*h-1); 44 i = i+2*h; 45 } 46 if(i < n-h+1) 47 merge(a,b,i,i+h-1,n); 48 else{ 49 int k; 50 for(k = i; k<=n; k++) 51 b[k] = a[k]; 52 } 53 } 54 void mergesort(int a[],int b[],int n) 55 { 56 int h = 1; 57 while(h < n){ 58 mergepass(a,b,n,h); 59 h = h*2; 60 mergepass(b,a,n,h); 61 h = h*2; 62 } 63 }
上述三种算法只有归并排序是稳定的,其余两个都不稳定。
堆排序用在筛选数组中最大(小)的K个数,快速排序用在查找数组的第K大(小)数。归并排序性能相对较好。