一、四种基本的排序方法(以由大到小为例)及空间时间复杂度:
1)简单排序
void xz_sort(int a[],int n)
{int i,j,t,max;
for(i=0;i<n-1;i++) //第i+1个数与后面的数比较
{
max=i;
for(j=i+1;j<n;j++) //分别与后面的数作比较
if(a[max]<a[j]) max=j; //找到符合要求顺序的就给改变下标
if(max!=i) t=a[max],a[max]=a[i],a[i]=t;
}
}
2)冒泡排序
void mp_sort(int a[],int n)
{
int i,j;
int t;
for(i=0;i<n-1;i++) //每次循环后保留后面i+1个数
for(j=0;j<n-1-i;j++) //比较n-1-i次大小
if(a[j]<a[j+1]) t=a[j+1],a[j+1]=a[j],a[j]=t;
}
3)插入排序
void cr_scort(int a[],int n)
{
int i,j,t;
for(i=1;i<n;i++) //全扫一遍研究值
{
t=a[i]; //保留研究值
j=i; //制造多个变量,不用i的原因是二重循环中会改变i值,导致混乱
while(j>0&&t>a[j-1]) //整体的循环对前i个数排好顺序,直到找到比研究值大的前一位数停止。这时该研究值的下标为j
{
a[j]=a[j-1]; //当找到比研究值大的数,就用a[i-1]填a[i]
j--; //作用:使前面的数值有序
}
a[j]=t; //补坑(注:前面的j--)
}
4)折半插入排序
/*void zbcr_scort(int a[],int n)
{
int j,i,x,r,l;
for(i=1;i<n;i++)
{
l=0,r=i-1;
x=a[i];
int m=(l+r)/2;
//二分法找应插入的位置
while(l<=r&&x!=a[m])
{
if(x<a[m]) l=m+1;
else if(x>=a[m]) r=m-1;
m=(l+r)/2;
}
for(j=i;j>=l;j--) //注:j>=l。因为导致while循环退出后l>r故应插入的位置为r~l之间
a[j]=a[j-1];
a[l]=x;
}
}
=====================================================================================================
排序方法 | 最好情况 | 最坏情况 | 平均情况 | 稳定性 | 空间复杂度 |
---|---|---|---|---|---|
冒泡排序 | O(n) | O(n^2) | O(n^2) | 稳定 | 0(1) |
快速排序 | O(nlogn) | O(n^2) | O(nlogn) | 不稳定 | 0(logn) |
简单选择排序 | O(n^2) | O(n^2) | O(n^2) | 不稳定 | 0(1) |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | 不稳定 | 0(1) |
直接插入排序 | O(n) | O(n^2) | O(n^2) | 稳定 | 0(1) |
折半插入排序 | O(n^2) | 稳定 | 0(1) | ||
希尔排序 | O(n1.3) | 不稳定 | 0(1) | ||
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | 稳定 | O(n) |
基数排序 | O(d(r+n)) | 稳定 | O(n) |
===============================================================
二、快速排序的理解
以由大到小的顺序排序为例:
void quick_sort(int a[],int l,int r)
{
int axis;
if(l<r) //中轴axis
{
axis=adjust(a,l,r);
quick_sort(a,l,axis-1);
quick_sort(a,axis+1,r);
}
}
int adjust(int a[],int l,int r) //有思想,有看头
{
int x=a[l];
while(l<r)
{
while(l<r&&x<=a[r]) //若符合由小到大的规律
r--; //改变指向以保留
a[l]=a[r]; //有重复
while(l<r&&x>=a[l])
l++;
a[r]=a[l];
}
a[l]=x;
return l;
}
解题步骤:
a.把第一个数(研究数)付给中间值t,空出空位
b.若右边的数找到比t大的数时,把空填上,并再次空出一个空位。
c.再如果从左往右找到比t小的数时,把该数赋给空位,并再次空出一空位。
d.重复b、c直到研究数左边的都是大于其的数,有右边的都是小于其的数。
e.不断平分左右区间,重复b~d步骤,直到平分的区间只有一个元素。