以上排序都属于内部排序,希尔排序属于插入排序,堆排序属于选择排序,
对排序的各种实现:直接上代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int a[1000];
long sum=0;
void swap(int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
void merge(int x,int y)//归并
{
int mid=(x+y)/2;int k=x;
int left[505];
int right[505];
int n1=mid-x+1;
int n2=y-mid;
for (int i=0;i<n1;i++)
{
left[i]=a[x++];
}
for (int j=0;j<n2;j++)
{
right[j]=a[x++];
}
i=j=0;
while(i<n1&&j<n2)
{
if (left[i]<right[j])
{
a[k++]=left[i++];
}
else
{
a[k++]=right[j++];
sum+=n1-i;//此处可以记录交换的次数
}
}
while (i<n1)
{
a[k++]=left[i++];
}
while (j<n2)
{
a[k++]=right[j++];
}
}
void mergesort(int x,int y)//时间复杂度是O(nlogn)
{
if (x<y)
{
int mid=(x+y)/2;
mergesort(x,mid);
mergesort(mid+1,y);
merge(x,y);
}
}
void insertsort(int n)//时间复杂度O(n^2)
{
int i,j,temp;
for (i=0;i<n;i++)
{
temp=a[i];
for (j=i;j>0&&a[j-1]>temp;j--)//在i元素前的所有比i大的元素向后移动一个位置 为i空出一个位置
{
a[j]=a[j-1];
}
a[j]=temp;
}
}
void quicksort(int x,int y)//时间复杂度O(nlogn)
{
if (x>=y) return ;
int sign=a[y];
int low=x-1;
int high=y;
while(low<high)
{
while (low<y&&a[++low]<sign);//low指针向后找到第一个比sign小的
while (high>0&&a[--high]>sign);//high指针向前找到第一个比sign大的
if (low<high) swap(low,high);
}
swap(y,low);
quicksort(x,low-1);
quicksort(low+1,y);
}
//堆是完全二叉树,子节点的父节点是(i-1)/2
//父节点的子节点是i*2+1,i*2+2
void heap(int x,int y)
{
int i,j;
int temp=a[x];
while (x<y/2)
{
int k=2*x+1;
if (k+1<y&&a[k]<a[k+1]) ++k;//在子节点中找一个大的与根值互换
if (temp>a[k]) break;
a[x]=a[k];
x=k;
}
a[x]=temp;
}
//堆的一个性质:最大元素在根处,最小元素是某个叶节点
void heapsort(int n)//最坏的情况下,时间复杂度O(nlogn)
{
int i;
int x=n/2-1;
for (i=x;i>=0;i--)//更新所有的根节点,使形成堆
{
heap(i,n);
}
for (i=n-1;i>0;i--)//堆排序 每次更新到最下面的是最大的树
{
swap(0,i);//0-i是具有堆性质
heap(0,i);
}
}
void shillsort(int n)
{
int i,j;
int t=1;
while (t<n/4) t=t*2+1;//设置增量
while (t>0)
{
for (i=t;i<n;i++)//对每一块排序
{
j=i;
int d=a[i];
while(j>=t&&a[j-t]>d)
{
a[j]=a[j-t];
j-=t;
}
a[j]=d;
}
t/=2;//增量变小(即合并过程)
}
}
int length(int n)
{
int i,l=1,p=10;
for (i=0;i<n;i++)
{
while(a[i]>=p)
{
p*=10;
l++;
}
}
return l;
}
//基数排序是稳定排序
void radixsort(int n)
{
int i,flag=1,j,k;
int len=length(n);//确定关键字的个数
int temp[1005];
int cnt[10];
for (i=0;i<len;i++)
{
for (j=0;j<10;j++)
{
cnt[j]=0;
}
for (j=0;j<n;j++)//按尾数确定分组(桶)
{
k=(a[j]/flag)%10;
cnt[k]++;
}
for(j=1;j<10;j++)
{
cnt[j]=cnt[j]+cnt[j-1];
}
for (j=n-1;j>=0;j--)//根据桶确定新的顺序
{
k=(a[j]/flag)%10;
cnt[k]--;
temp[cnt[k]]=a[j];
}
for (j=0;j<n;j++)
{
a[j]=temp[j];
}
flag*=10;//第一次从个位数排序,然后对十位数,以此类推、、、
}
}
int main()
{
//freopen("Input.txt","r",stdin);
int n;
while(cin>>n)
{
for (int i=0;i<n;i++)
{
cin>>a[i];
}
//mergesort(0,n-1);对两个有序序列进行归并的排序
//insertsort(n);把比i小的元素前移一个位置,然后插入i
//quicksort(0,n-1);左边都比右边小
//heapsort(n);确定堆,更新堆底元素
//shillsort(n); 以增量为分组排序
//radixsort(n);以关键字排序
for (int j=0;j<n;j++)
{
cout<<a[j]<<" ";
}
}
return 0;
}
注:选择排序在最好的情况下的时间复杂度是O(N)
关于几种排序的一个形象效果图地址:
http://www.cnblogs.com/wangfupeng1988/archive/2011/12/26/2302216.html