直接插入排序:

直接插入排序通过线性搜索来确定待排序记录的位置,在待排序记录的前面形成一个单调的序列,对已排序记录按照从大到小依次逐个进行比较。直到找到适合的位置(具体情况根据增减)。时间效率为O(n^2),空间效率为O(1),最好时间代价为O(n),最差时间代价为O(n^2)。直接插入排序对于基本有序的短序列排序的效率比较高,所以,之后几种算法的优化都可以利用直接插入排序这一特性。

 

 
  
  1. void insertSort(int a[], int n){ 
  2.     int i,j,tmp; 
  3.     if(n <= 1){return ;} 
  4.     for(i=1 ; i<n ; i++){ 
  5.         tmp = a[i]; 
  6.         j = i-1; 
  7.         while(j >= 0 &&  a[j] > tmp){ 
  8.             a[j+1] = a[j]; 
  9.             j--; 
  10.         } 
  11.         a[j+1] = tmp; 
  12.     } 

希尔排序:

先将序列分成若干子序列,而且要保证子序列中的记录在原始的数组中不相邻,而且间距相同,分别对这些小队列进行排序。,然后减少记录间距,减少子序列个数,将原始序列分成更大、更有序的序列,进行插入排序,直到最后间距为一。希尔排序实质上是对于直接插入排序效率的一种折中,直接插入排序的适用短而基本有序的序列。希尔排序在排序的不同时期分别利用到了直接插入排序的优点。前期主要是采用排序短的序列,后期排列基本有序的长序列,可以说希尔排序,就是利用直接插入排序的优点,有针对性地对序列进行优化。时间复杂度:O(n^3/2)(跟序列的状态无关),空间复杂度O(1)。还有这种排序是不稳定的,因为他不是通过比较相邻记录实现插入的排序。

 

 
  
  1. void shellSort(int a[], int n){ 
  2.     int i,delta; 
  3.     for(delta=n/2; delta > 0; delta /= 2){ 
  4.         for(i = 0; i<delta; i++){ 
  5.             insertModSort(&a[i],n-i,delta); 
  6.         } 
  7.     } 
  8.     insertModSort(a,n,1); 
  9.  
  10. void insertModSort(int a[],int n,int delta){ 
  11.     int i,j,tmp; 
  12.     for(i=delta; i<n ; i+=delta){ 
  13.         tmp = a[i]; 
  14.         j = i - delta; 
  15.         while(j>=0  &&  a[j] > tmp){ 
  16.             a[j+delta] = a[j]; 
  17.             j -= delta; 
  18.         } 
  19.         a[j+delta] = tmp; 
  20.     } 

直接选择排序:

选择排序的原理很简单,就是扫描整个数组,找出最大值或最小值,然后把这个值与最前的记录交换。接着从第二个记录开始,扫描一遍数组,找出最大或最小值与第二个记录交换,如此反复,知道最后一个记录为止,整个数组有序。时间代价与记录的初始排列无关为O(n^2),空间代价为O(1)。直接选择排序,每一趟排序都是直接从线性剩余记录中查找最大记录,没有利用到之前的结果,故而效率较低。

 

 
  
  1. void selectSort(int a[], int n){ 
  2.     int i,j,s,tmp; 
  3.     if(n <= 1) 
  4.         return; 
  5.     for(i=0; i<n; i++){ 
  6.         s = i
  7.         for(j = i+1; j<n ; j++ ){ 
  8.             if(a[s]>a[j]){ 
  9.                 s = j
  10.             } 
  11.         } 
  12.         tmp = a[i]; 
  13.         a[i] = a[s]; 
  14.         a[s] = tmp; 
  15.     } 

堆排序:

堆排序也是一种基于选择的排序。它是采用一种树形堆结构来储存剩余记录,而树形的堆结构的调整花费的时间是O(log(n)),因而比较高效。时间代价为O(n*log(n)),空间代价刚好为:O(1),排序主要分成两步:

1.对所有记录建最大堆,具体参照建堆的思路。

2.取出堆顶最大记录与数组末端的数进行交换,然后调整堆,如此往复,直到堆建好为止。

 

冒泡排序:

这是一种基于交换的排序,通过不停的比较相邻记录,然后实现基本有序。时间代价:O(n^2),空间代价:O(1)。

 

 
  
  1. void bubbleSort(int a[] , int n){ 
  2.     int i,j,tmp; 
  3.     bool isSort = true
  4.     for(i=0;i<n;i++){ 
  5.         for(j=n-1;j>i;j--){ 
  6.             if(a[j-1] > a[j]){ 
  7.                 tmp = a[j]; 
  8.                 a[j] = a[j-1]; 
  9.                 a[j-1] = tmp; 
  10.                 isSort = false
  11.             } 
  12.         } 
  13.         iftrue ==isSort){ 
  14.             break
  15.         } 
  16.     } 

快速排序:

这是我最喜爱的一种排序方法,快排对于随机状态的排序效率最高。这个一种基于分治法的排序算法,关键在于分、治、合,最终合并成一个可行解,时间效率为O(n*log(n)),空间效率为:O(log(n))。快排是一个不稳定的排序算法算法步骤如下:

1.从带排记录中选出一个记录作为轴值;

2.将剩余记录分割成左子序列L和右子序列R;

3.L中的所有记录都小于轴值,R中的记录都大于等于轴值;

4.对子序列L、R进行递归调用,直到子序列中只含有0或1个记录的序列,退出递归调用。

 

 
  
  1. void quickSort(int a[], int l, int r){ 
  2.     if(l >= r) 
  3.         return
  4.     int left = l,right = r; 
  5.     int pivot = a[l]; 
  6.     while(true){ 
  7.         while(l<r  && a[r]>=pivot) 
  8.             r--; 
  9.         if(l<r){ 
  10.             a[l] = a[r]; 
  11.             l++; 
  12.         } 
  13.         while(l<r && a[l]<=pivot) 
  14.             l++; 
  15.         if(l<r){ 
  16.             a[r] = a[l]; 
  17.             r--; 
  18.         } 
  19.         if(l == r){ 
  20.             a[l] = pivot; 
  21.             break
  22.         } 
  23.     } 
  24.     quickSort(a,left,l-1); 
  25.     quickSort(a,l+1,right); 

 

归并排序:

这也是一种采用分治法的排序方法,它将原始序列划分成两个子序列,然后分别对子序列递归,最后将子序列合并,一个典型的分,治,合的思想。时间代价为O(n*log(n)),空间代价为O(n)。需要一个额外的临时数组,与快排不同,归并排序是一种稳定的排序。思路如下:

1.将原始序列分成两个子序列;

2.分别对两个子序列进行递归进行归并排序;

3.将这两个已经排好的子序列归并到一个数组里;

 

桶排序:

桶排序是完全不同于之前排序算法,他是基于收集的分配排序函数。因而他的时间代价可以达到O(m+n),空间代价为O(m+n),m为排序值的区间长度,因而是一个十分高效的排序算法,但是它的适用的范围有限,它适用于区间跨度较小(m的值较小)的待排序列。

基数排序:

基数排序是基于桶排序的,我们可以认为他是针对桶排序的一种优化,它将排序码拆分成多个部分进行比较。如果要对0~9999之间的整数进行排序,那么只需要将数字拆成个、十、百、千,分别对这四个进行桶排序,当然我们得采用低位优先法,方便我们的程序实现。时间代价为O(d*(n+r)),空间代价为O(n+r)。