常用排序算法(未完)

 

常用的排序算法的时间复杂度和空间复杂度

 

排序法

最差时间分析 平均时间复杂度 稳定度 空间复杂度
冒泡排序 O(n2) O(n2) 稳定 O(1)
快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n)
选择排序 O(n2) O(n2) 稳定 O(1)
二叉树排序 O(n2) O(n*log2n) 不一顶 O(n)

插入排序

O(n2) O(n2) 稳定 O(1)
堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)
希尔排序 O O 不稳定 O(1)

 以上都是常用的基于比较排序方法,时间复杂度的下限是O(n*logn),可以用决策树证明。

 

【1】选择排序,插入排序,冒泡排序

三种比较简单,而且复杂度都是O(n^2) 的方法

 1 //选择排序
 2 template <class T>
 3 void SelectSort(T A[], int n)
 4 { 
 5       int small;
 6 for (int i=0; i<n-1; i++) {        //执行n-1趟
 7          small=i;                        //先假定待排序序列中第一个元素为最小
 8     for (int j=i+1;j<n;j++)         //每趟扫描待排序序列n-i-1次
 9          if (A[j]<A[small]) small=j; //如果扫描到一个比最小值元素还小的,则记下其下标
10       Swap(A[i],A[small]);            //最小元素与待排序序列中第一个元素交换
11   }
12 }
13 // ==========================================================
14 //直接插入排序
15 template <class T>
16 void InsertSort(T A[], int n)
17 { 
18   for(int i=1; i<n; i++){                //执行n-1趟
19         int j=i;
20         T temp=A[i];                      //待插入元素存入临时变量
21 while (j>0 && temp<A[j-1]){       //从后往前查找插入位置
22             A[j]=A[j-1];  j--;             //A[j-1]元素后移,j指针前移
23         }
24         A[j]=temp;                         //待插入元素存入找到的插入位置
25   }
26 } // ==========================================================
27 //冒泡排序
28 template <class T>
29 void BubbleSort(T A[], int n)
30 { 
31        int i,j,last;
32  i=n-1;                    
33  while (i>0){                    //最多进行n-1趟
34       last=0;                     //进入循环就将last置成0
35      for (j=0; j<i; j++)          //从上往下进行相邻元素的两两比较
36        if (A[j+1]<A[j]){      
37             Swap(A[j],A[j+1]);  //由于后者小,故交换
38               last=j;              //有交换就将last置成j
39        }
40     i=last;                        //如果一趟排序中没有交换元素,则last为0
41 }
42 } // ==========================================================

 

 

【2】快排

 1 template< class T>
 2 void QuickSort(T A[],int low,int high)
 3 {
 4     if (low >= high) return;        
 5 
 6     //划分过程:取一个基准值,将数组分成两段
 7     int mid = (low+high)/2;
 8     int pivot = A[mid];
 9     swap(A[low],A[mid]);
10 
11     int pl = low +1, pr = high;
12     while(pl < pr) {
13         while (A[pl] <= pivot) pl++;
14         while (A[pr] > pivot) pr--;
15 
16         if(pl < pr) swap(A[pl],A[pr]);
17     }
18     A[low] = A[pr];
19     A[pr] = pivot;
20 
21     //递归过程:对两段分别进行快排
22     QuickSort(A,low,pr-1);
23     QuickSort(A,pr+1,high);
24 }

 简洁的Python版本

1 def qsort(L):
2     if not L: return []
3     return qsort([x for x in L[1:] if x< L[0]]) + L[0:1] + \
4            qsort([x for x in L[1:] if x>=L[0]])

 

【3】归并排序

 

 1 template <class T>                                 
 2 void Merge(T A[],int i1,int j1,int i2,int j2)
 3 {
 4     // i1,j1是子序列1的下、上界,i1,j2是子序列2的下、上界
 5     T *Temp=new T[j2-i1+1];             //分配能存放两个子序列的临时数组
 6     int i=i1,j=i2,k=0;                   //i,j是两个子序列的游动指针,k是Temp的游动指针
 7     while (i<=j1&&j<=j2)                //若两个子序列都不空,则循环
 8         if (A[i]<=A[j]) Temp[k++]=A[i++];   //将A[i]和A[j]中较小的存入Temp[k]
 9         else Temp[k++]=A[j++];
10     while (i<=j1) Temp[k++]=A[i++];     //若第一个子序列中还有剩余的就存入Temp
11     while (j<=j2) Temp[k++]=A[j++];     //若第二个子序列中还有剩余的就存入Temp
12     for (i=0; i<k; i++) A[i1++]=Temp[i]; //将临时数组中的元素倒回A
13     delete [] Temp;
14 }
15 
16 template <class T>
17 void MergeSort(T A[], int n)
18 {
19     int i1,j1,i2,j2;      //i1,j1是子序列1的下、上界,i2,j2是子序列2的下、上界
20     int size=1;                      //子序列中元素个数,初始化为1。
21     while (size<n) {
22         i1=0;
23         while (i1+size<n) { //若i1+size<n,则说明存在两个子序列,需再两两合并
24             i2=i1+size;                  //确定子序列2的下界
25             j1=i2-1;               //确定子序列1的上界
26             if (i2+size-1>n-1)
27                 j2=n-1;  //若第2个子序列中不足size个元素,则置子序列2的上界j2=n-1
28             else 
29                 j2=i2+size-1;        //否则有size个,置j2=i2+size-1
30             Merge(A,i1,j1,i2,j2);     //合并相邻两个子序列
31             i1=j2+1;                  //确定下一次合并第一个子序列的下界
32         }
33         size*=2;                     //元素个数扩大一倍
34     }
35 }

 【堆排序】

# heapSort.py
import random 
def buildHeap(li):
    for i in xrange(len(li)/2-1,-1,-1):
        ajustHeap(li,i,len(li))

def ajustHeap(li,n,end): 
    if 2*n+1 < end and li[n] < li[2*n+1] :
        li[n],li[2*n+1] = li[2*n+1],li[n]
        ajustHeap(li,2*n+1,end)
    if 2*n+2 < end and li[n] < li[2*n+2] :
        li[n],li[2*n+2] = li[2*n+2],li[n]
        ajustHeap(li,2*n+2,end)

def heapSort(li): 
    buildHeap(li)
    for i in xrange(len(li)-1,0,-1):
        li[i],li[0] = li[0],li[i]
        ajustHeap(li, 0, i)
    return li
 
if __name__ == '__main__':
    a= [random.randint(1,100) for i in range(20)]  
    print heapSort(a)

 

 

 

 

posted @ 2012-07-16 15:03  Keosu  阅读(341)  评论(0编辑  收藏  举报