zoukankan      html  css  js  c++  java
  • [转载+修改]计数排序

    计数排序法是一种简单的排序方法,这种排序算法对一个待排序的数组进行排序,并将排序结果放到另一个新的数组中。计数排序算法针对待排序数组中的每个记录,扫描待排序的数组一趟,统计待排序数组中有多少个记录的值比该记录的值小。假设针对某一个记录,统计出的计数值为c,那么,这个记录在新的有序数组中的合适的存放位置即为c。

     

      假设有三个数组:

     

      数组 A:待排序数组(非空,数据个数n)

     

      数组 B:排序后的数组

     

      数组 count(用c代表):纪录A中某个数据在表B中的位置,初始值为0

     

      对于A中某个数据Xi(0<=i<n),与表中各个数据Xj(0<=i<n)进行比较,记录下比Xi小的值的个数到count[i]。但是,我们发现,数据与自身的比较是多余的,而且当Xi与Xj比较后,就没有必要再比较Xj和Xi了。在此基础上我们对之前的操作方式进行一些变化。我们对A中的数据Xi与Xj进行比较,所不同的是Xj的j的范围为 i<j<=n ,即每个Xi只和其后的数据进行比较。在比较过程中,如果Xi > Xj ,则count[i] = count[i]+1;否则,count[j]=count[j]+1 。当算法完毕的时候,count数组中就记录了A中的各个数据在B中的实际位置。算法过程如下所示:

    View Code
    //其中a为输入,b为输出,n为元素个数
    void count_sort_base(int a[], int b[], int n)
    {
        int i;
        int j;
        int *c = new int[n];
        memset(c,0,n * sizeof(int));
        for(i = 0; i < n-1; i++)
        {
            for(j = i+1; j < n; j++)
            {
                if(a[i] > a[j])
                    c[i]++;
                else
                    c[j]++;
            }
        }
        for(i = 0; i < n; i++)
            b[c[i]] = a[i];
        delete []c;
    }

    改进版:计数排序是一个非基于比较的线性时间排序算法。它对输入的数据有附加的限制条件:

     

      1、输入的线性表的元素属于有限偏序集S;

     

      2、设输入的线性表的长度为n,|S|=k(表示集合S中元素的总数目为k),则k=O(n)。

     

      在这两个条件下,计数排序的复杂性为O(n)。

     

      计数排序算法的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有17个元素的值小于x的值,则x可以直接存放在输出序列的第18个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。

     

      假设输入的线性表L的长度为n,L=L1,L2,..,Ln;线性表的元素属于有限偏序集S,|S|=k且k=O(n),S={S1,S2,..Sk};则计数排序算法可以描述如下:

     

      扫描整个集合S,对每一个Si∈S,找到在线性表L中小于等于Si的元素的个数T(Si);

     

      扫描整个线性表L,对L中的每一个元素Li,将Li放在输出线性表的第T(Li)个位置上,并将T(Li)减1。

     

      具体的实现如下:

    View Code
    //其中a为输入,b为输出,n为元素个数,k为最大元素
    void count_sort_upgrade(int a[], int b[], int n, int k)
    {
        int j;
        int *c = new int[k+1];
        memset(c, 0, (k+1) * sizeof(int));
        for (j = 0; j < n; j++) 
            c[a[j]]++;                    //求出重复的数字出现多少次
        for (j = 1; j <= k; j++) 
            c[j] += c[j - 1];            //求出不比数字j大的元素的个数,包括相等的
        for (j = n - 1; j >= 0; j--)  //注意此处不能写成for(int j = 0; j < n; j++),否则会造成排序算法的不稳定
        {
            b[c[a[j]] - 1] = a[j];
            c[a[j]]--;
        }
        delete []c;
    }

     

     

    如原创文章,转载请注明:转自http://www.cnblogs.com/xpowerlord/
  • 相关阅读:
    windows定时任务schtasks命令详细解
    TCP/IP 详解7 Ping指令
    Vue JSX、自定义 v-model
    DOM 元素的循环遍历
    关于 Blob
    Vue.nextTick 的应用解析
    弹窗组件及其回调函数
    krry-transfer ⏤ 基于 element 的升级版穿梭框组件发布到 npm 啦
    防抖与节流 & 若每个请求必须发送,如何平滑地获取最后一个接口返回的数据
    Java 单文件、多文件上传 / 实现上传进度条
  • 原文地址:https://www.cnblogs.com/xpowerlord/p/2446248.html
Copyright © 2011-2022 走看看