1.最简单的排序——桶排序(简化版)
优点:快速,简单
缺点:数据足够大时,会造成严重的空间浪费;不能解决小数问题
理解:桶排序就是开一个足够大的数组,数组下标最大值(设为x,a[x])要大于需要排序的数据最大值。设输入为ni,则只要令a[ni]++,就可以确定相同ni的个数,然后从从0到n,只要a[ni]不为0就可以按顺序正确的输出ni。另外由于桶排序的特殊性,桶排序还能够解决元素重复问题。
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1010];
int main()
{
int n,ni,i;
scanf("%d",&n);
fill(a,a+n,0);
for(i=1; i<=n; i++)
{
scanf("%d",&ni);
a[ni]++;
}
for(i=1; i<=1000; i++)//浪费空间
if(a[i])
while(a[i]--)//不输出重复元素的话就不需要这一行
printf("%d ",i);
return 0;
}
2.冒泡排序
优点: 能解决小数问题,稳定
缺点: 时间复杂度O(N2);
理解: 冒泡排序的核心就是双重嵌套for循环,每次比较相邻的两个元素,如果他们的顺序错误,就交换。冒泡冒泡,每一趟只能确定将一个数交换。由于冒泡排序每次只比较相邻两个元素。
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[20];
int main()
{
int n,j,i,t;
scanf("%d",&n);
fill(a,a+n,0);
for(i=0; i<n; i++)
scanf("%d",&a[i]);
for(i=0; i<n-1; i++)
for(j=0; j<n-1-i; j++)
if(a[j]>a[j+1])
{//注意别把i,t搞混了
t=a[j];a[j]=a[j+1];a[j+1]=t;
}
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
3.快速排序
优点: 极快
缺点: 不稳定
理解: 每次排序的时候设置一个基准点,将小于等于基准点的数放左边,反之放右边。这样交换的时候就不会想冒泡排序那样每次只搞定相邻的了。快排的每次排序是跳跃式的,运用了二分思想。
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1020],n;
struct node
{
int tim;
int cre;
}b[100];
void insertsort(node A[],int n) //结构体从大到小快排
{
for(int p=1;p<n;p++)
{
int tmp=A[p].cre;
int tmp2=A[p].tim;
int i=p;
for(;i>0&&A[i-1].cre<tmp;i--)
{
A[i].tim=A[i-1].tim;
A[i].cre=A[i-1].cre;
}
A[i].cre=tmp;
A[i].tim=tmp2;
}
}
void quick(int l,int r)
{
int i,j,t,temp;
if(l>r) return;
i=l;j=r;
temp=a[l];
while(i!=j)
{
while(a[j]>=temp&&i<j) j--;
while(a[i]<=temp&&i<j) i++;
if(i<j)
t=a[i],a[i]=a[j],a[j]=t;
}
a[l]=a[i];
a[i]=temp;
quick(l,i-1);
quick(i+1,r);
return;
}
int main()
{
int j,i,t;
scanf("%d",&n);
fill(a,a+n,0);
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
quicksort(1,n);
for(i=1; i<=n; i++)
printf("%d ",a[i]);
return 0;
}
4.堆排序
优点: 快,时间复杂度O(NlogN)
缺点: 堆排序将需要做两个步骤:建堆,排序(调整堆)。所以一般在小规模的序列中不合适,
理解: 可以建立最大堆,每次将第一个和最后一个元素互换,然后最大元素到了最后一位归位,再接着调整顶部元素再将堆的大小减1。
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1020],n;
void swap(int i,int j)
{
int t;
t=a[i];a[i]=a[j];a[j]=t;
return;
}
void siftdown(int i) //下沉函数,确保堆的正确性
{
int t,flag=0;
while(i*2<=n&&flag==0)
{
if(a[i]<a[i*2])
t=i*2;
else t=i;
if(i*2+1<=n)
{
if(a[t]<a[i*2+1])
t=2*i+1;
}
if(t!=i)
{
swap(t,i);i=t;
}
else flag=1;
}
return;
}
void headsort()
{
while(n>1)
{
swap(1,n);
n--;
siftdown(1); //将最后一位换到第一位,然后调整。
}
return;
}
int main()
{
int j,i,t,num;
scanf("%d",&num);
n=num;
for(i=1; i<=num; i++)
scanf("%d",&a[i]);
for(i=n/2;i>=1;i--) //建堆
siftdown(i); //调整
headsort();
for(i=1; i<=num; i++)
printf("%d ",a[i]);
return 0;
}