排序算法(2.11) | ||
O(N2) | ||
简单排序 | 从序列中找到最小数,与第一个数交换;再从剩下的数中,找到最大数,与第二个数交换 | 比较次数为N(N-1)/2 O(N2) |
冒泡排序 | 从后往前,相邻两个数进行比较,如前一个数大于后一个数,交换,如此一轮最小位于第一位;重复,交换至第二位。。 | 比较次数为N(N-1)/2,相较上者交换次数减小 O(N2) |
插入排序 | 一个个插入 | O(N2) |
希尔排序 | 升级版冒泡排序,比较间隔由大至小减小,N/2,N/4,...,1 | 降低交换次数 O(N2) |
O(NlogN) | ||
快速排序 | 选择一个基准,双指针,一个从头,一个从尾,头小于等于基准,尾大于基准,不满足时交换;然后分别递归对前后段递归使用,此种方法在序列大小大于某个阈值时使用。 基准选择标准可以是头、尾、中间值三者的中位数。 | 最好时间复杂度为O(NlogN),每次正好平分;最差情况为O(N2),为一个斜二叉树,每次分为一个跟剩下的。 平均为O(NlogN) |
堆排序※ | 先生成堆,将第一个元素与最后一个元素交换,剩下的n-1个元素再生成堆。 向下调整成为堆。(从小到大排序应该形成最大堆) | 平均为O(NlogN) |
归并排序※ | 分而治之,关键在于合并函数。 一开始就声明一个临时内存,节省空间。 | O(NlogN) |
void swap(int& a,int& b){
int tmp=a;
a=b;
b=tmp;
}
/***简单排序***/
void SimpleSort(int a[],int n){
for(int i=0;i<n;i++){
int mini=i;
for(int j=i+1;j<n;j++)
if(a[j]<a[mini]) mini=j;
if(mini!=i) swap(a[mini],a[i]);
}
}
/***插入排序***/
void InsertSort(int a[],int n){
for(int i=0;i<n;i++){
int tmp=a[i];
int j=i-1;
for(;j>=0;j--){
if(a[j]>tmp) a[j+1]=a[j];
else break;
}
a[j+1]=tmp;
}
}
/***冒泡排序***/
void PopSort(int a[],int n){
for(int i=0;i<n;i++){
for(int j=n-1;j>i;j--)
if(a[j]<a[j-1]) swap(a[j],a[j-1]);
}
}
/***希尔排序***/
void XierSort(int a[],int n){
for(int k=n/2;k>0;k/=2){
for(int i=k;i<n;i++)
for(int j=i-k;j>=0;j-=k)
if(a[j+k]<a[j]) swap(a[j+k],a[j]);
}
}
/***快速排序***/
int median(int a,int b,int c){
int res=(a>b)?a:b;
return (res<c)?res:c;
}
void partion(int a[],int left,int right){
if(right-left>2){
int mid=(left+right)/2;
int thresh=median(a[left],a[right],a[mid]);
int i=left,j=right;
while(i<j){
while(a[i]<thresh) i++;
while(a[j]>thresh) j--;
if(i<j) swap(a[i],a[j]);
}
partion(a,left,i-1);
partion(a,i+1,right);
}else{
for(int i=left;i<=right;i++){
int tmp=a[i];
int j=i-1;
for(;j>=left;j--)
if(a[j]>tmp) a[j+1]=a[j];
else break;
a[j+1]=tmp;
}
}
}
void QuickSort(int a[],int n){
partion(a,0,n-1);
}
/***堆排序***/
void adjustDown(int a[],int i,int n){
int child,tmp=a[i];
for(;2*i+1<n;i=child){
child=2*i+1;
if(child!=n-1&&a[child+1]>a[child]) child++;
if(a[child]>tmp) a[i]=a[child];
else break;
}
a[i]=tmp;
}
void HeapSort(int a[],int n){
for(int i=n/2;i>=0;i--)
adjustDown(a,i,n);
for(int i=n-1;i>0;i--){
swap(a[0],a[i]);
adjustDown(a,0,i);
}
}
/***归并排序***/
void Merge(int a[],int tmpa[],int left,int mid,int right){
int numElem=right-left+1;
int tp=left,leftend=mid-1;
while(left<=leftend&&mid<=right){
if(a[left]<a[mid]) tmpa[tp++]=a[left++];
else tmpa[tp++]=a[mid++];
}
while(left<=leftend) tmpa[tp++]=a[left++];
while(mid<=right) tmpa[tp++]=a[mid++];
for(int i=0;i<numElem;i++,right--)
a[right]=tmpa[right];
}
void Msort(int a[],int tmpa[],int left,int right){
if(right>left){
int mid=(left+right)/2;
Msort(a,tmpa,left,mid);
Msort(a,tmpa,mid+1,right);
Merge(a,tmpa,left,mid+1,right);
}
}
void MergeSort(int a[],int n){
int *tmpa=(int*)malloc(n*sizeof(int));
Msort(a,tmpa,0,n-1);
free(tmpa);
}
int main(){
int a[10]={3,5,2,4,6,8,7,1,0,9};
int b[10]={3,5,2,4,6,8,7,1,0,9};
SimpleSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
InsertSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
PopSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
XierSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
QuickSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
HeapSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
MergeSort(a,10);
for(int i=0;i<10;i++){
printf("%d ",a[i]);
a[i]=b[i];
}
printf("\n");
return 0;
}