常用排序算法(未完)
常用的排序算法的时间复杂度和空间复杂度
排序法 |
最差时间分析 | 平均时间复杂度 | 稳定度 | 空间复杂度 |
冒泡排序 | 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 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 }
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]])
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)