• 时空权衡之计数排序


    计数排序是输入增强的一个例子,针对待排序列表(A[])的每一个元素,算出列表中小于该元素的元素个数,并把结果记录在一张表(count[])中,个数之处了该数在有序表中的位置。

    例如:A[7]={62,31,84,96,19,47}

    其中62有3个数字小于62,分别是19 31 47,A[0]=62,count[0]=3,这里3就是小于62的数的个数。

    算法流程:

    for  i<-0  to n-1 do count[i]<-0

    for  i<-0  to n-2 do

          for  j<-i+1  to n-1 do

                if A[i]<A[j]

                        count[j]<-count[j]+1

                 else

                         count[i]<-count[i]+1

    for  i<-0  to n-1  so S[count[i]]<-A[i]

    #include<iostream>
    using namespace std;
    int main()
    {
        int A[1001];//可排序数组
        int count[1001];//
        int S[1002];//存好已经排好序的数组
        int n,j,i;
        cin>>n;//输入数据大小
        for(i=0;i<n;i++)
        {
            cin>>j;
            A[i]=j;
            count[i]=0;
        }//输入数据
        for(i=0;i<=n-2;i++)
        {
            for(j=i+1;j<=n-1;j++)
            {
                if(A[i]<A[j])
                {
                    count[j]++;
                }
                else
                    count[i]++;
            }
        }
        for(i=0;i<=n-1;i++)
            S[count[i]]=A[i];
        for(i=0;i<n;i++)
            cout<<S[i];
        return 0;
    }

    算法的效率如何?

    该算法的基本操作为if(A[i]<A[j]),一共执行次数{n(n-1)}/2次,所以该算法执行键值比较次数和选择排序的一样多,而且占用了线性数量的额外空间。

    考虑另外一种计数方法:分布计数

    这种排序方法是线性效率的,用空间换时间、利用输入列表的特性,使得效率大大提升。

    算法伪代码:

    DistributionCountingSort(A[0...n-1],l,u)

    //分布计数法,对来自有限范围整数的一个数组进行排序

    //输入:数组A[0..n-1],数组的整数位于l和u之间

    //输出:A中的元素构成的非降序数组S[0..n-1]

    for  j<-0 to u-1  do  D[j]<-0

    for  i<-0 to  n-1  do  D[A[i]-l]++;

    for  j<-1 to  u-l  do  D[j]=D[j-1]+D[j]//重新计算分布

    for  i<-n  downto   0  do 

          j<-A[i]-l

          S[D[j]-1]<-A[i]

          D[j]<-D[j]-1

    return S

    #include<iostream>
    using namespace std;
    int main()
    {
        int A[1001];//可排序数组
        int D[1001];
        int S[1002];//存好已经排好序的数组
        int n,j,i,l,u;
        cin>>n;//输入数据大小
        cin>>l>>u;//数组元素大小在[l,u]之间
        for(i=0;i<n;i++)
        {
            cin>>j;
            A[i]=j;
        }//输入数据
        int d;
        d=u-l;//数组元素最大值与最小值的差值
        for(j=0;j<=d;j++)//统计分布计数的数组
            D[j]=0;
        for(i=0;i<=n-1;i++)//对A[i]的元素统计计数
            D[A[i]-l]++;
        for(j=1;j<=d;j++)//重新计算计数
            D[j]=D[j-1]+D[j];
        for(i=n-1;i>=0;i--)
        {
            j=A[i]-l;
            S[D[j]-1]=A[i];
            D[j]--;
        }
        for(i=0;i<n;i++)
            cout<<S[i]<<" ";
    return 0;
    }

    明显这是效率为线性的一个算法,这是遇到过时间效率最好的算法,但是显然需要的空间比较多

  • 相关阅读:
    学习篇之函数就是对象
    @Controller和@RestController的区别
    maven 阿里云 国内镜像 中央仓库
    IntelliJ IDEA使用教程
    解决“无法从套接字读取更多数据”
    at java.util.Arrays.copyOfRange(Arrays.java:3209)导致的java.lang.OutOfMemoryError: Java heap space 错误的解决办法
    maven中引入ojdbc包
    Oralce增加表空间
    Web服务框架发展与REST服务开发
    Oralce解锁表
  • 原文地址:https://www.cnblogs.com/biong-blog/p/4431914.html
Copyright © 2020-2023  润新知