常用排序汇总

常用排序有:

1.插入排序(直接插入排序,折半插入排序,希尔排序)

2.交换排序(冒泡排序,快速排序)

3.选择排序(直接选择排序,堆排序)

4.归并排序

5.基数排序


/*
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;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值