选择排序
选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,至此选择排序完成。
以下面5个无序的数据为例:
56 12 80 91 20(文中仅细化了第一趟的选择过程)
第1趟:12 56 80 91 20
第2趟:12 20 80 91 56
第3趟:12 20 56 91 80
第4趟:12 20 56 80 91
代码略
归并排序:
时间复杂度:O(n*lgn)
白书模板,需要辅助空间
int cnt; void merge_sort(int *a,int x,int y,int *t) { if(y-x>1) { int m=(x+y)>>1; int p=x,q=m,i=x; merge_sort(a,x,m,t); merge_sort(a,m,y,t); printf("** %d %d %d\n",x,y,m); while(p<m||q<y) { if(q>=y||(p<m&&a[p]<=a[q])){ printf("i=%d p=%d\n",i,p); t[i++]=a[p++]; } else { printf("i=%d q=%d\n",i,q); t[i++]=a[q++]; cnt+=m-p;//计算逆序数 } } for(i=x;i<y;i++)a[i]=t[i]; } }
快速排序:不稳定。
请写出快速排序思路和代码
http://blog.csdn.net/v_july_v/article/details/6116297
时间复杂度:O(n*lgn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
快速排序时基于分治模式处理的,
对一个典型子数组A[p...r]排序的分治过程为三个步骤:
1.分解:
第一趟遍历N个数的数组,把小于等于A[r]的划在左边,大于A[r]的划在右边
A[p..r]被划分为俩个(可能空)的子数组A[p ..q-1]和A[q+1 ..r],使得
A[p ..q-1] <= A[q] <= A[q+1 ..r]
2.解决:通过递归调用快速排序,对子数组A[p ..q-1]和A[q+1 ..r]排序。
3.合并。
举一个具体而完整的例子。
来对以下数组,进行快速排序,
2 8 7 1 3 5 6 4(主元)
#include<iostream> #include<cstdio> using namespace std; int PARTITION(int *A,int p,int r) { int x=A[r]; int i=p-1; int tmp; for(int j=p;j<=r-1;j++) { if(A[j]<=x){ i=i+1; tmp=A[i]; A[i]=A[j]; A[j]=tmp; } } tmp=A[i+1]; A[i+1]=A[r]; A[r]=tmp; return i+1; } void QUICKSORT(int *A,int p,int r) { if(p<r){ int q=PARTITION(A,p,r); // printf("---------------------------\n"); // for(int i=0;i<8;i++)printf("%d %d\n",i,A[i]); QUICKSORT(A,p,q-1); QUICKSORT(A,q+1,r); } } int main() { int a[10]={2,4,7,1,3,5,6,8}; QUICKSORT(a,0,7); for(int i=0;i<8;i++)printf("%d %d\n",i,a[i]); }
练习题: