• 几种排序算法的C++实现——快速排序、堆排序、基数排序


    排序算法是非常常见的面试笔试问题,考查的一个人的基本功,本文将一些排序做了C++的实现,就当是做个学习总结吧。

    1、快速排序

      快速排序的中心是填坑法,取一个数(这里选取第一个数)作为基准数temp,从队尾开始寻找第一个比基准数小的数a[j],交换a[j]和temp,然后队首开始查找第一个比temp大的数a[i],交换之,遍历的结果是当i>=j时,temp左边的数都小于temp,后边的数都大于temp,这个有点像归并排序。最后利用递归调用完成排序,代码如下:

     1 void QuickSort(int a[], int l,int r){
     2     if(l<r){
     3         int i=l,j=r,temp=a[l];
     4         while(i<j){
     5             while(i<j&&temp<=a[j])
     6                 --j;
     7             if(i<j)
     8                 a[i++]=a[j];
     9 
    10             while(i<j&&temp>a[i])
    11                 ++i;
    12             if(i<j)
    13                 a[j--]=a[i];
    14         }
    15         a[i]=temp;
    16         QuickSort(a,l,i-1);
    17         QuickSort(a,i+1,r);
    18     }
    19 }

      在笔试题中很多人选择快速排序作为基础算法对数组进行排序,一般认为快速排序是内部排序中最好的排序法之一,其平均时间复杂度为O(nlogn),但在已经完成排序的情况下,其最坏复杂度可以为O(n^2),且不稳定。

    2、堆排序

      堆排序是基于完全二叉树的排序方法,其中心思想是首先构造最大堆(或最小堆),即父节点总是大于其子节点,然后将堆化的数组a[0]与a[i]交换,即将最大数置于i位置,再将0—i的继续堆化,重新选出最大的数于a[0],完成第一个排序。经过遍历完成排序,其代码为:

     1 //构造最大堆
     2 void MaxHeapFixDown(int a[], int i, int n){
     3     int j = 2*i+1;
     4     int temp = a[i];
     5     while(j<n){
     6         if(j+1<n&&a[j]<a[j+1])
     7             ++j;
     8         if(temp>a[j])
     9             break;
    10         else{
    11             a[i]=a[j];
    12             i=j;
    13             j=2*i+1;
    14         }
    15     }
    16     a[i]=temp;
    17 }
    18 
    19 //堆排序
    20 void HeapSort(int a[], int n){
    21     for(int i= n/2-1;i>=0;i--)
    22         MaxHeapFixDown(a,i,n);
    23     for(int i=n-1;i>=1;i--){
    24         swap(a[i],a[0]);
    25         MaxHeapFixDown(a,0,i);
    26     }
    27 }

      堆排序相对快速排序最大的有点时即便在最坏的情况下其复杂度也能达到O(nlogn),但也是不稳定排序.

    3、基数排序

      基数排序中心思想是基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。具体介绍可以参考http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html,代码如下:

     1 //寻找数组中最大数的位数作为基数排序循环次数
     2 int KeySize(int a[], int n){
     3     int key = 1;
     4     for(int i=0;i<n;i++){
     5         int temp = 1;
     6         int r = 10;
     7         while(a[i]/r>0){
     8             temp++;
     9             r*=10;
    10         }
    11         key = (temp>key)?temp:key;
    12     }
    13     return key;
    14 }
    15 
    16 //基数排序
    17 void RadixSort(int a[], int n){
    18     int key = KeySize(a,n);
    19     int bucket[10][10]={0};
    20     int order[10]={0};
    21     for(int r = 1;key>0;key--,r*=10){
    22         for(int i=0;i<n;i++){
    23              int lsd = (a[i]/r)%10;
    24              bucket[lsd][order[lsd]++]=a[i];
    25         }
    26 
    27         int k = 0;
    28         for(int i = 0;i<10;i++){
    29             if(order[i]!=0){
    30                 for(int j = 0;j<order[i];j++)
    31                     a[k++]=bucket[i][j];
    32             }
    33             order[i]=0;
    34         }
    35     }
    36 }

      基数排序是稳定算法,效率很高,其复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数。但它只能用在整数的排序中,且需要借助一定的辅助空间。

    *************************************************************************

    先暂时跟新到这。。。。。



  • 相关阅读:
    virtualbox 设置鼠标在虚拟机和电脑之间切换
    7-nginx 配置记录 http 请求参数(如记录URL参数)的 log 和 nginx 常见的一些内置变量
    BufferedWriter 没有比FileWriter 快多少
    锁、线程锁、锁旗标、锁对象
    all 2 branches missed
    使用xmp path进行行变列的SQL语句
    程序员的健身课
    zookeeper启动报错:Error: Could not find or load main class org.apache.zookeeper.server.quorum.QuorumPeerMain
    clickhouse数仓:mysql数据到clickhouse的离线、实时与全量、增量的方案调研
    sql语句分为三类(DML,DDL,DCL)
  • 原文地址:https://www.cnblogs.com/cityflickr/p/3896109.html
Copyright © 2020-2023  润新知