常用排序有:
1.插入排序(直接插入排序,折半插入排序,希尔排序)
2.交换排序(冒泡排序,快速排序)
3.选择排序(直接选择排序,堆排序)
/*
Author:Ibsen
Data:2015.12.21
*/
//排序汇总(插入排序(3种),交换排序(2种),选择排序(2种))
#include <iostream>
using namespace std;
int R[]={2,4,6,8,0,9,7,5,3,1},n=10;
//插入排序:
void Insert_Sort(int R[],int low,int high)
{//直接插入排序:时间O(n^2),空间O(1),稳定
for(int i=low+1;i<=high;++i)
{
int tmp=R[i],j=i-1;
for(;j>=low&&R[j]>tmp;--j) //从右向左在有序区R[0..i-1]中找R[i]的插入位置
R[j+1]=R[j]; //从右向左在有序区R[0..i-1]中找R[i]的插入位置
R[j+1]=tmp; //在j+1处插入R[i]
}
}
void Insert_Half_Sort(int R[],int low,int high)
{//折半插入排序:时间O(n^2),空间O(1),稳定
for(int i=low+1;i<=high;++i)
{
int tmp=R[i],head=low,tail=i-1;
while(head<=tail) //二分查找R[i]的插入位置
{
int mid=(head+tail)>>1;
if(tmp>=R[mid]) head=mid+1;
else tail=mid-1;
}
for(int j=i-1;j>tail;--j) //大于R[i]的元素后移
R[j+1]=R[j];
R[tail+1]=tmp; //插入R[i]
}
}
void Shell_Sort(int R[],int low,int high)
{//希尔排序:时间O(n^1.3),空间O(1),不稳定
int gap=(high-low+1)>>1; //增量的初始值
while(gap)
{
for(int i=low+gap;i<=high;++i) //对所有相隔gap位置的元素组采用直接插入排序
{
int tmp=R[i],j=i-gap;
for(;j>=low&&R[j]>tmp;j-=gap) //对相隔gap位置的元素组进行排序
R[j+gap]=R[j];
R[j+gap]=tmp;
}
gap>>=1; //减小增量
}
}
//交换排序:
void Bubble_Sort(int R[],int low,int high)
{//冒泡排序:时间O(n^2)(差于直接插入排序),空间O(1),稳定
for(int i=low;i<high;++i)
{
bool is_exchange=false; //标记本趟冒泡是否有元素交换,若没有,则说明已经有序
for(int j=high;j>i;--j) //比较,找出本趟冒泡的最小关键字
{
if(R[j]<R[j-1]) //交换两个数
{
int tmp=R[j];
R[j]=R[j-1];
R[j-1]=tmp;
is_exchange=true;
}
}
if(!is_exchange) return ;
}
}
void Quick_Sort(int R[],int low,int high)
{//快速排序:时间O(n*logn),空间O(logn),不稳定
int i=low,j=high;
if(i<j) //区间至少存在两个元素
{
int tmp=R[i]; //用区间的第i个元素作为基准
while(i!=j) //从区间两端交替向中间扫描,直至i==j为止
{
while(i<j&&R[j]>=tmp) --j; //从右到左扫描,找到第一个小于tmp的R[j]
R[i]=R[j];
while(i<j&&R[i]<=tmp) ++i; //从左到右扫描,找到第一个大于tmp的R[i]
R[j]=R[i];
}
R[i]=tmp;
Quick_Sort(R,low,i-1); //对左区间递归排序
Quick_Sort(R,i+1,high); //对右区间递归排序
}
}
//选择排序
void Select_Sort(int R[],int low,int high)
{//直接选择排序:时间O(n^2),空间O(1),不稳定
for(int i=low;i<high;++i) //做第i趟排序
{
int k=i;
for(int j=i+1;j<=high;++j) //在当前无序区R[i..n-1]找出最小的R[k]
if(R[j]<R[k]) k=j;
if(k!=i) //交换R[k]和R[i]
{
int tmp=R[i];
R[i]=R[k];
R[k]=tmp;
}
}
}
//堆排序
void sift(int R[],int low,int high)
{//堆排序调整函数
int i=low,j=low*2;
int tmp=R[i]; //R[j]是R[i]的左孩字
while(j<=high)
{
if(j<high&&R[j]<R[j+1]) ++j; //若右孩子较大,把j指向右孩子
if(tmp<R[j]) //将R[j]调整到双亲节点上去
{
R[i]=R[j];
i=j; //修改i和j的值,以便向下筛选
j=2*i;
}
else break;
}
R[i]=tmp; //被筛选的节点的值放入最终位置
}
void Heap_Sort(int R[],int n)
{//堆排序:时间O(n*logn),空间O(1),不稳定
for(int i=n/2;i>=1;i--) //循环建立初始堆
sift(R,i,n);
for(int i=n;i>=2;i--) //进行n-1趟堆排序,每一趟排序元素个数减少1
{
int tmp=R[1]; //将无序区最后一个元素与当前堆顶元素互换
R[1]=R[i];
R[i]=tmp;
sift(R,1,i-1); //重新调整剩下的堆
}
}
void Display(int R[],int low,int high)
{//打印输出
for(int i=low;i<=high;++i)
cout<<R[i]<<" ";
cout<<endl;
}
int main()
{
//Insert_Sort(R,0,n-1);
//Insert_Half_Sort(R,0,n-1);
//Shell_Sort(R,0,n-1);
//Bubble_Sort(R,0,n-1);
//Quick_Sort(R,0,n-1);
//Select_Sort(R,0,n-1);
Heap_Sort(R,n); //堆排序需要数组下标从1开始
Display(R,0,n-1);
return 0;
}