• 各种排序算法的代码


      1 // ALLKindsOfSorts.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 #include "stdafx.h"
      5 #include<iostream>
      6 #include<vector>
      7 #include<bitset>
      8 
      9 using namespace std;
     10 
     11 ////////////////////////////////////////所有的排序总结////////////////////////////////////
     12 
     13 //1、冒泡排序(O(n*n))
     14  void MaopaoSort(int *a,int len)
     15  {
     16      //这里要明白
     17     for(int i=0;i<len-1;i++)////这层循环控制的是需要排序的数的个数,即控制扫面的轮数
     18     {
     19         bool  IsChange=false;//这是冒泡改进的地方,增加一个标志来判断是否已经提前排好序了
     20         //这里要注意由于比较的是在一个循环下前一个数跟后一个数比较
     21         for(int j=0;j<len-i-1;j++)//这层循环是控制每一轮扫描之后,将最大的数放在最右边
     22         {//这里的j<len-i-1要注意边界的原因,所以是j<len-i-1
     23             if(a[j]>a[j+1])//相邻元素比较
     24             {
     25                 //交换
     26                 int temp=a[j];
     27                 a[j]=a[j+1];
     28                 a[j+1]=temp;
     29                 IsChange=true;//如果一次扫描完之后都没发生任何的交换,则表明已经排好序了
     30             }
     31         }
     32         if(!IsChange)
     33         {
     34             cout<<"提前结束排序"<<endl;
     35             return;
     36         }
     37     }
     38  }
     39 
     40  //2、插入排序(O(n*n))
     41 void InsertSort(int *a,const int len)
     42  {
     43 
     44     for(int i=1;i<len;i++)//扫描无序的数组
     45     {
     46         //记住:将第一个数作为已排序的数,从第二个数开始所有的数作为无序的数
     47         if(a[i-1]>a[i])//跟已排序好的数进行比较,找出合适的位置
     48         {        
     49             int temp= a[i];//将需要插入的无序数保存起来,并将所有都大于该需要插入的无序数的数后移
     50             int j=i-1;
     51             while(j>=0&&a[j]>temp)//从后往前扫描(j>=0是边界条件),判断已排序的数是否大于需要插入的无序数
     52             {
     53                 a[j+1]=a[j];//如果不是合适的位置就往后移动,腾出位置出来
     54                 j--;
     55             }
     56             a[j+1]=temp;//找到了合适的位置,执行插入
     57         }
     58     }
     59 
     60  }
     61 
     62 //3、归并排序O(nlog(n))
    struct Node{int v;Node* next}
    
    Node* merge_sort(Node* p){
        if(p==NULL||p->next==NULL){
            return NULL;	
        }
        Node* head1=p;
        Node* mid=getmid(p);
    
        Node* head2=mid->next;
        mid->next=NULL;
    
        head1=merge_sort(head1);
        head2=merge_sort(head2);
    
        return merge(head1,head2)
    
    }
    
    
    Node* getmid(Node* p){
        if(p==NULL||p->next==NULL){
        return NULL;	
        }
        Node* fast=p;
        Node* slow=p;
        while(fast->next!=NULL){
            fast=fast->next;
            if(fast->next!=NULL){
            fast=fast->next;
            slow=slow->next;
            }
        }
        return slow
    
    }
    
    Node* merge(Node* p1,Node* p2){
        if(p1==NULL) return p2;
        if(p2=NULL) return p1;
    
        Node* head1=p1;
        Node* head2=p2;
        Node* newhead=NULL;
    
        if(head1->val<=head2->val){
            newhead=head1;
            head1=head1->next;
        }else{
            newhead=head2;
            head2=head2->next;
        }
    
        Node* ptemp=newhead;
        while(head1&&head2){
            if(head1->val<=head2->val){
            ptemp->next=head1;
            ptemp=head1;
            head1=head1->next;
            }else{
            ptemp->next=head2;
            ptemp->head2;
            head2=head2->next;
            }
        }
    
        ptemp->next=head1?head1:head2;
        return newhead;
    }
    
                    
    
    
    

      

     
    102 //4、桶排序O(n)
    103  //桶排序用到插入排序(O(n*n))
    104 void InsertSort(vector<int>&a,const int len)
    105  {
    106 
    107     for(int i=1;i<len;i++)//扫描无序的数组
    108     {
    109         //记住:将第一个数作为已排序的数,从第二个数开始所有的数作为无序的数
    110         if(a[i-1]>a[i])//跟已排序好的数进行比较,找出合适的位置
    111         {        
    112             int temp= a[i];//将需要插入的无序数保存起来,并将所有都大于该需要插入的无序数的数后移
    113             int j=i-1;
    114             while(j>=0&&a[j]>temp)//从后往前扫描(j>=0是边界条件),判断已排序的数是否大于需要插入的无序数
    115             {
    116                 a[j+1]=a[j];//如果不是合适的位置就往后移动,腾出位置出来
    117                 j--;
    118             }
    119             a[j+1]=temp;//找到了合适的位置,执行插入
    120         }
    121     }
    122 
    123  }
    124 
    125 //由于桶排序需要将数据分成n等份的范围,每个范围的个数不一样,因此每个桶里面装的数的个数不相同,
    126 //因此选用容器作为桶的数据结构
    127 void BucketSort(vector<int> &result,int *Data,int len)
    128 {
    129     if(Data==NULL||len<=0)
    130         return ;
    131     //求原始数据的最大值与最小值
    132     int max_value=Data[0];
    133     int min_value=Data[0];
    134     for (int i=0;i<len;i++)
    135     {
    136         if(Data[i]>max_value)
    137             max_value=Data[i];
    138         if(Data[i]<min_value)
    139             min_value=Data[i];
    140     }
    141     //将数据分成n等份范围的桶
    142     int k=(max_value-min_value+1)/10+1;//10个桶范围
    143     vector<int > Bucket[10];
    144     //将数据分别装入相应的桶中
    145     for (int i=0;i<len;i++)
    146     {
    147         for(int j=0;j<10;j++)
    148         {
    149             if(Data[i]<min_value+(j+1)*k)
    150             {
    151                 Bucket[j].push_back(Data[i]);
    152                 break;//将某数放进桶内后进行下一个数
    153             }
    154         }
    155     }
    156     //分别对每一个桶内部进行排序,选用的方法是插入排序
    157     for (int i=0;i<10;i++)
    158     {
    159         InsertSort(Bucket[i],Bucket[i].size());
    160     }
    161     //依次输出每一个桶中的元素
    162     for(int i=0;i<10;i++)
    163     {
    164         for (vector<int>::size_type it=0;it<Bucket[i].size();it++)
    165         {
    166             result.push_back(Bucket[i][it]);
    167             //cout<<Bucket[i][it]<<" ";
    168         }
    169     }
    170 
    171 }
    172 
    173 //5、基数排序 O(max) max是最大值的位数
    174 int GetPos(int a,int pos)
    175 {
    176     int temp=1;
    177     for (int i=1;i<pos;i++)
    178         temp*=10;
    179     return (a/temp)%10;
    180 }
    181 
    182 
    183 void RadixSort(int *a,int len,int pos)
    184 {
    185     if(a==NULL||len<=0)
    186         return ;
    187     vector<int> temp[10];//10表示十进制
    188 
    189     //将数据放入桶中
    190     for (int i=0;i<len;i++)
    191     {
    192         //a[i]%10表示的是0-9的数
    193         temp[GetPos(a[i],pos)].push_back(a[i]);
    194     }
    195 
    196     //按桶的顺序输出数据
    197     for(int i=0;i<10;i++)
    198     {
    199         for (vector<int>::size_type it=0;it<temp[i].size();it++)
    200         {
    201             *(a++)=temp[i][it];
    202         }
    203     }
    204 }
    205 
    206 void RadisSort( int *a,int len)
    207 {
    208     if(a==NULL||len<=0)
    209         return ;
    210     int max=a[0];
    211     for(int i=0;i<len;i++)//求出最大值,就可以知道需要排序的次数,即排序的次数等于最大值的位数
    212     {
    213         if(a[i]>max)
    214             max=a[i];
    215     }
    216     int pos=1;//用来指定按哪一位来排序,最初是右边第一位
    217     do
    218     {
    219         //RadixSort(a,len,pos);//也可以采用函数调用的方式,避免调整指针的指向,因为在调用函数时,指针进行了复制,原始指针并没有改变
    220 
    221         vector<int> temp[10];//10表示十进制
    222 
    223         //将数据放入桶中
    224         for (int i=0;i<len;i++)
    225         {
    226             //a[i]%10表示的是0-9的数
    227             temp[GetPos(a[i],pos)].push_back(a[i]);
    228         }
    229 
    230         //按桶的顺序输出数据
    231         for(int i=0;i<10;i++)
    232         {
    233             for (vector<int>::size_type it=0;it<temp[i].size();it++)
    234             {
    235                 *(a++)=temp[i][it];//这里要注意修改了指针本身的值
    236             }
    237         }
    238         //因此这里要重新调整指针指向第一个元素
    239         for(int i=0;i<len;i++)//求出最大值,就可以知道需要排序的次数,即排序的次数等于最大值的位数
    240         {
    241             a--;
    242         }
    243 
    244         pos++;
    245     }
    246     while(max=max/10);
    247 
    248 }
    249 
    250 
    251 
    252 //////////////以下是不稳定的排序//////////////////////////////////
    253 //6、选择排序O(n*n)
    254 void swap(int &a,int&b)
    255 {
    256     int temp;
    257     temp=a;
    258     a=b;
    259     b=temp;
    260 }
    261 void SelectSort(int *a,int len)
    262 {
    263     if(a==NULL||len<=0)
    264         return ;
    265     for (int i=0;i<len;i++)//需要选择n次
    266     {
    267         //a[i]每次选择的临时选择的最小值
    268         //将临时最小值跟后面的数进行比较,判断是否是真的最小值
    269         for(int j=i;j<len;j++)
    270         {
    271             if(a[j]<a[i])//如果发现比最小值还小的元素则进行交换
    272                 swap(a[i],a[j]);
    273         }
    274     }
    275 }
    276 
    277 //7、希尔排序 O(n*n)
    278 
    279 void ShellSort(int *a,int len)
    280 {
    281     if(a==NULL||len<=0)
    282         return ;
    283     for (int i=len/2-1;i>=1;i--)//控制增量的循环
    284     {
    285         for (int j=i;j<len;j=j+i)//控制需要插入元素的个数
    286         {
    287             int temp=a[j];//待插入的元素
    288             int k=j-i;
    289             if(a[k]>temp)
    290             {
    291                 while(k>=0&&a[k]>temp)//查找合适的位置
    292                 {
    293                     a[k+i]=a[k];//按照增量的方式,将大的数按照增量的大小往后移增量个位置
    294                     k=k-i;//按照增量的方式递减
    295                 }
    296                 //找到合适的位置后,执行插入操作
    297                 a[k+i]=temp;
    298             }
    299         }
    300     }
    301 }
    302 
    303 //8、快速排序
    304 
    305 void QuickSort(int *a,int left,int right)
    306 {
    307     if(a==NULL||left<0||right<0)
    308         return ;
    309     int i=left,j=right;
    310     if(left<right)
    311     {
    312         //每次都是取第一个数来作为基准,并把它拿出来,腾出一个空位用作排序
    313         int temp=a[i];//这里可以改进:就是选取中值或平均值作为基准,只需将它们跟第一个数进行交换位置即可,在按照相同的办法进行
    314         while(i<j)//当i=j时,表明一次排序已经结束,此时对应的i的位置就是
    315         {
    316             //由于开始状态是第一个位置作为第一个空位子
    317             //从右向左找出比基准小的数
    318             while(i<j&&a[j]>=temp)//若退出循环就是找到了比基准小的数
    319             {
    320                 j--;
    321             }
    322             if(i<j)
    323             {
    324                 a[i]=a[j];//发现右边存在比基准小的数,则将右边的数放到左边来,留下一个位置
    325             }
    326             //由于a[j]是右边留下的一个位置,因此可以从左边找出一个比基准大的数来填
    327             //从左向右找出比基准大的数
    328             while(i<j&&a[i]<=temp)//若退出循环就是找到了比基准大的数
    329             {
    330                 i++;
    331             }
    332             if(i<j)
    333             {
    334                 a[j]=a[i];
    335             }
    336         }
    337         //此时i表示原来第一个元素应该放置的正确的位置
    338         a[i]=temp;//将原来假设第一个位置放到他正确的位置上
    339         ////一次排序结束,即已经将基准值放到正确的位置上了,下面是递归排序左右两边的序列
    340         QuickSort(a,left,i-1);
    341         QuickSort(a,i+1,right);
    342     }
    343 }
    344 
    345 //9、堆排序
    346 //通过比较二叉树父节点和左右节点的大小来调整
    347 void HeapAdjust(int *a,int i,int size)  //调整堆 i>=1,size是序列长度
    348 {
    349     int lchild=2*i;       //i的左孩子节点序号 
    350     int rchild=2*i+1;     //i的右孩子节点序号 
    351     int max=i;            //父节点 
    352     if(i<=size/2)          //如果i是叶节点就不用进行调整 
    353     {
    354         //判断父节点和左右之节点的大小,找出最大值
    355         if(lchild<=size&&a[lchild]>a[max])
    356         {
    357             max=lchild;
    358         }    
    359         if(rchild<=size&&a[rchild]>a[max])
    360         {
    361             max=rchild;
    362         }
    363         //如果最大值不是父节点
    364         if(max!=i)
    365         {
    366             swap(a[i],a[max]);//则进行交换
    367             //继续比较,直到所有的父节点都比较完为止
    368             HeapAdjust(a,max,size);//由于max的值没变,因此最大值就是根节点  
    369         }
    370     }        
    371 }
    372 
    373 void BuildHeap(int *a,int size)    //建立堆 
    374 {
    375     //由于需要确保最后根节点是最大值,因此是从下往上开始建堆
    376     for(int i=size/2;i>=1;i--)    //非叶节点最大序号值为size/2 
    377     {
    378         HeapAdjust(a,i,size);
    379         for(int i=1;i<=10;i++)
    380             cout<<a[i]<<" ";
    381         cout<<endl;
    382     }    
    383 } 
    384 
    385 void HeapSort(int *a,int size)    //堆排序 
    386 {
    387     BuildHeap(a,size);//首先建堆
    388     //再排序
    389     for(int i=size;i>=1;i--)
    390     {//每次将最大值放入最后一个位置中,对剩下的进行调整
    391         swap(a[1],a[i]);//交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面 
    392         HeapAdjust(a,1,i-1);//重新调整堆顶节点成为大顶堆
    393     }
    394 } 
    395 
    396 
    397 
    398 int _tmain(int argc, _TCHAR* argv[])
    399 {
    400     //int a[10]={0,11,21,31,41,56,6,7,8,9};
    401     //int b[5]={1,2,3,4,5};
    402     //cout<<"排序之前的值:"<<endl;
    403     //for (int i=0;i<10;i++)
    404     //    cout<<a[i]<<" ";
    405     //cout<<endl;
    406     //vector<int> c;
    407     //MeageSort(c,a,10,b,5);
    408 
    409     //BucketSort(c,a,10);
    410     //RadisSort( a,10);
    411 
    412     //cout<<"排序之后的值:"<<endl;
    413     //for (int i=0;i<10;i++)
    414     //    cout<<a[i]<<" ";
    415     //cout<<endl;
    416     /*
    417     float a=1.0f;
    418     cout<<sizeof(a)<<endl;
    419     cout<<(int)a<<endl;
    420     cout<<&a<<endl;
    421     cout<<(int &)a<<endl;
    422     cout<<boolalpha<<((int)a==(int&)a)<<endl;
    423     
    424     float b=0.0f;
    425     cout<<sizeof(b)<<endl;
    426     cout<<(int)b<<endl;
    427     cout<<&b<<endl;
    428     cout<<(int &)b<<endl;
    429     cout<<boolalpha<<((int)b==(int&)b)<<endl;
    430     
    431     int a[10]={0,11,21,31,41,56,6,7,8,9};
    432     for (int i=0;i<10;i++)
    433         cout<<a[i]<<" ";
    434     cout<<endl;
    435     QuickSort(a,0,9);
    436     for (int i=0;i<10;i++)
    437         cout<<a[i]<<" ";
    438          //int a[]={0,16,20,3,11,17,8};*/
    439     //这里需要注意,对排序是从a[1]开始排序,因此,待排序的数要从a[1]开始
    440     int a[11]={0,11,21,31,41,56,6,7,8,9,10};
    441     HeapSort(a,10);
    442     for(int i=1;i<=10;i++)
    443         cout<<a[i]<<" ";
    444     cout<<endl;
    445   
    446     return 0;
    447 }
  • 相关阅读:
    react路由传参的三种方式:
    毕设登录逻辑分析
    redis缓存数据库的配置和分析
    c#窗体虚线图形验证码设计
    C#窗体技巧
    关于子窗体的层级关系
    安装SQL SERVER开启SA用户登录的方法
    SQL中CONVERT日期不同格式的转换用法
    sql server中自连接的使用
    IFieldEdit Interface 接口
  • 原文地址:https://www.cnblogs.com/ljy2013/p/3825045.html
Copyright © 2020-2023  润新知