各种排序算法总结

常用的一些排序算法的时间复杂度、空间复杂度以及稳定性如下表所示:图片来自https://www.cnblogs.com/fnlingnzb-learner/p/9083552.html 

                     è¿éåå¾çæè¿°

下面是各种排序算法的测试代码:

#include <iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
void show(const int &n)
{
    cout<<n<<" ";
}
/**************冒泡排序******************/
void maopao(vector<int>obj)
{
    for(int i=0;i<obj.size()-1;++i)
        for(int j=0;j<obj.size()-i-1;++j)
    {
        if(obj.at(j)>obj.at(j+1))
        swap(obj.at(j),obj.at(j+1));
    }
    for_each(obj.begin(),obj.end(),show);
}
/**************选择排序******************/
void selec(vector<int>obj)
{
    for(int i=0;i<obj.size()-1;++i)
        for(int j=i+1;j<obj.size();++j)
    {
        if(obj[i]>obj[j])
            swap(obj[i],obj[j]);
    }
    for_each(obj.begin(),obj.end(),show);
}
/**************插入排序******************/
void insert(vector<int>obj)//插入排序适用于小规模,部分有序的排序过程,效率较高
{
    for(int i=1;i<obj.size();++i)
    {
       int numi=obj[i];//此处一定要记录一下,因为插入时将会覆盖
       int j;
       for(j=i-1;j>=0&&numi<obj[j];--j)
        obj[j+1]=obj[j];  //移动所有大于obj[i]的数
       obj[j+1]=numi;  //将obj[i]插入
    }
    for_each(obj.begin(),obj.end(),show);
}

/**************堆排序******************/
void adjust(vector<int>&obj,int size,int index)
{
    int left=index*2+1;
    int right=index*2+2;
    int maxin=index;
    if(left<size&&obj[left]>obj[maxin]) maxin=left;
    if(right<size&&obj[right]>obj[maxin]) maxin=right;
    if(maxin!=index)
    {
        swap(obj[index],obj[maxin]);
        adjust(obj,size,maxin);
    }
}
void heap(vector<int>obj)
{
    for(int i=obj.size()/2-1;i>=0;--i)
        adjust(obj,obj.size(),i);
    for(int j=obj.size()-1;j>=1;--j)
    {
        swap(obj[0],obj[j]);
        adjust(obj,j,0);
    }
    for_each(obj.begin(),obj.end(),show);
}
/**************快速排序******************/
int part_qs(vector<int>&obj,int left,int right)
{
    int temp=right;
    while(left<right)
    {
        while(left<right&&obj[left]<=obj[temp])
            ++left;
        while(left<right&&obj[right]>=obj[temp])
            --right;
        swap(obj[right],obj[left]);
    }
    swap(obj[temp],obj[left]);
    return left;
}

void qs(vector<int>&obj,int left,int right)
{
      if(left>right)
        return ;
      int mid=part_qs(obj,left,right);
      qs(obj,left,mid-1);
      qs(obj,mid+1,right);
}

/**************归并排序******************/
void merge_gb(vector<int>&obj,int left,int mid,int right)
{
     vector<int>temp;
     int l=left,m=mid+1,r=right;
     while(l<=mid&&m<=r)
     {
         if(obj[l]<obj[m]) {temp.push_back(obj[l]);++l;}
         else {temp.push_back(obj[m]);++m;}
     }
     while(l<=mid)
     {
         temp.push_back(obj[l]);++l;
     }
     while(m<=r)
     {
         temp.push_back(obj[m]);++m;
     }
     for(int i=0;i<temp.size();++i)
        obj[left+i]=temp[i];
}

void guibing(vector<int>&obj,int left,int right)
{
    if(left<right)
    {
        int mid=(left+right)/2;
        guibing(obj,left,mid);
        guibing(obj,mid+1,right);
        merge_gb(obj,left,mid,right);
    }
}

/**************希尔排序******************/
 void part_insert(vector<int>&obj,int gap,int t)//这里利用了插入排序
{
     int temp=obj[t];   //主要就是将原来的间隔1变为gap<=>h
     int j;
     for(j=t-gap;j>=0&&temp<obj[j];j-=gap)
        obj[j+gap]=obj[j];
     obj[j+gap]=temp;
}

void shell_sort(vector<int>&obj)
{
    for(int h=obj.size()/2;h>0;h/=2)
        for(int j=h;j<obj.size();++j)
        part_insert(obj,h,j);
    for_each(obj.begin(),obj.end(),show);
}

/***************基数排序(时间复杂度为O(d(n+k)))******************/
int get_max(vector<int>&obj)
{
      int sum=obj[0];
      for(int i=0;i<obj.size();++i)
      if(obj[i]>sum) sum=obj[i];
      return sum;
}

void radix_sort(vector<int>&obj)
{
    int maxnum=get_max(obj);
    int flag=0,radix=1;
    while(maxnum)
    {
        maxnum=maxnum/10;
        ++flag;
    }
    vector<int>temp(obj.size());
    vector<int>count(10);
    for(int i=0;i<flag;++i)
    {
          for(int j=0;j<10;++j)//首先将桶清零
            count[j]=0;
          for(int j=0;j<obj.size();++j)
          {
                  ++count[(obj[j]/radix)%10];
          }
          for(int j=1;j<10;++j)
            count[j]=count[j]+count[j-1]; //计算下标位置,很明显count[9]=n
          for(int j=obj.size()-1;j>=0;--j)//这里注意一定是从最后一个元素放桶
          {//这里必须要用倒叙,原因在于当前位若相同,则倒叙可以不影响之前较小位排序结果
              int k=(obj[j]/radix)%10;
              temp[count[k]-1]=obj[j];
              --count[k];
          }
          for(int k=0;k<obj.size();++k)
            obj[k]=temp[k];
          radix=radix*10;
    }
    for_each(obj.begin(),obj.end(),show);
}

void init()
{
    cout<<"*********************************\n";
    cout<<"*                               *\n";
    cout<<"*          排序系统             *\n";
    cout<<"*                               *\n";
    cout<<"*  1.冒泡     2.选择   3.插入   *\n";
    cout<<"*  4.堆排     5.快排   6.归并   *\n";
    cout<<"*  7.希尔     8.基排   9.Exit   *\n";
    cout<<"*                               *\n";
    cout<<"*********************************\n";
    cout<<"请输入你的选择:";
}

int main()
{
    init();
    int choice;
    cin>>choice;
    cout<<"请输入你想排序的元素个数:";
    int n;
    cin>>n;
    vector<int>num(n);
    cout<<"请输入你想进行排序的数列:";
    for(int i=0;i<n;++i)
        cin>>num[i];
    clock_t btime=clock();
    switch(choice)
    {
        case 1:
             maopao(num);
              break;
        case 2:
             selec(num);
              break;
        case 3:
             insert(num);
              break;
        case 4:
             heap(num);
              break;
        case 5:
             qs(num,0,num.size()-1);
             for_each(num.begin(),num.end(),show);
             break;
        case 6:
            guibing(num,0,num.size()-1);
            for_each(num.begin(),num.end(),show);
            break;
        case 7:
            shell_sort(num);
            break;
        case 8:
            radix_sort(num);
            break;
        default:break;
    }
    cout<<"此算法用时:"<<(clock()-btime)<<"ms"<<endl;
    return 0;
}

 测试结果如下:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值