[转载+修改]计数排序

计数排序法是一种简单的排序方法,这种排序算法对一个待排序的数组进行排序,并将排序结果放到另一个新的数组中。计数排序算法针对待排序数组中的每个记录,扫描待排序的数组一趟,统计待排序数组中有多少个记录的值比该记录的值小。假设针对某一个记录,统计出的计数值为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/
原文地址:https://www.cnblogs.com/xpowerlord/p/2446248.html