• 桶排序


    1、定义

        箱排序的变种。为了区别于上述的箱排序,姑且称它为桶排序(实际上箱排序和桶排序是同义词)。

    2、基本思想

        桶排序的思想是把[0,1)划分为n个大小相同的子区间,每一子区间是一个桶。然后将n个记录分配到各个桶中。因为关键字序列是均匀分布在[0,1)上的,所以一般不会有很多个记录落入同一个桶中。由于同一桶中的记录其关键字不尽相同,所以必须采用关键字比较的排序方法(通常用插入排序)对各个桶进行排序,然后依次将各非空桶中的记录连接(收集)起来即可。

        注意:

        这种排序思想基于以下假设:假设输入的n个关键字序列是随机分布在区间[0,1)之上。若关键字序列的取值范围不是该区间,只要其取值均非负,我们总能将所有关键字除以某一合适的数,将关键字映射到该区间上。但要保证映射后的关键字是均匀分布在[0,1)上的。

    3、桶排序算法

        伪代码算法为:

    void BucketSon(R)
        { //对R[0..n-1]做桶排序,其中0≤R[i].key<1(0≤i<n)
          for(i=0,i<n;i++) //分配过程.
            将R[i]插入到桶B[「n(R[i].key)」]中; //可插入表头上
          for(i=0;i<n;i++) //排序过程
            当B[i]非空时用插人排序将B[i]中的记录排序;
          for(i=0,i<n;i++) //收集过程
            若B[i]非空,则将B[i]中的记录依次输出到R中;
         }

     注意:

        实现时需设置一个指针向量B[0..n-1]来表示n个桶。但因为任一记录R[i]的关键字满足:0≤R[i].key<1(0≤i≤n-1),所以必须将R[i].key映射到B的下标区间[0,n-1)上才能使R[i]装入某个桶中,这可通过└n*(R[i].key)┘来实现。

    拓展:

    1、对输入的数据进行排序

    #include<stdio.h>
    int main(){
             int a[11];
             //得分从0~10
             int i,j,t;
             for(int i=0;i<=10;i++){
                      a[i]=0;
             }
            //对数组进行初始化
             for(int i=0;i<5;i++){
                      scanf("%d",&t);
                      a[t]++;
             //如果得分为5分,则a[4]=1,这是用来计算某一个得分出现的次数
             }
             for(int i=0;i<=10;i++)
                      for(int j=1;j<=a[i];j++){
                               printf("%d",i);
             //打印出对应的分数,即数组中第几个数字
                      }
             getchar();
             getchar();
            //用来暂停程序,以便查看程序的输出(这时不会出现“按任意键退出”的字样)
            //也可以采用system(“pause”);但是需要引入头文件#include<stdlib.h>
             return 0;
    }
    
    #上述程序是按照递增顺序排列,如果按照递减顺序排列,则只需修改如下代码:
             for(int i=10;i>=0;i--)
                      for(int j=1;j<=a[i];j++){
                               printf("%d",i);
                      }
    

    2、输入n个数据,对其排序

    #include<stdio.h>
    int main(){
             int book[1001];
             int i,j,n,t;
             for(int i=0;i<=1000;i++){
                      book[i]=0;
             }
             scanf("%d",&n);
            //限定输入的个数
             for(int i=0;i<n;i++){
                      scanf("%d",&t);
                      book[t]++;
             }
             for(int i=0;i<=1000;i++)
                      for(int j=1;j<=book[i];j++){
                               printf("%d  ",i);
            //如果需要输出结果之间有间隔,只需要在输出的占位符后面加上空格即可
                      }
             getchar();
             getchar();
             return 0;
    }
    注:这两个可以称之为桶排序,但是实际上桶排序要比这个复杂。
    其缺点在于:浪费空间,上述2中需要申请1001个内存空间;不能进行小数的排序。
    

      

    4、桶排序算法分析

        桶排序的平均时间复杂度是线性的,即O(n)。但最坏情况仍有可能是O(n2)。

        箱排序只适用于关键字取值范围较小的情况,否则所需箱子的数目m太多导致浪费存储空间和计算时间。

        【例】n=10,被排序的记录关键字ki取值范围是0到99之间的整数(36,5,16,98,95,47, 32,36,48)时,要用100个箱子来做一趟箱排序。(即若m=n2时,箱排序的时间O(m+n)=O(n2))。

  • 相关阅读:
    每日一个设计模式之策略模式
    Java发送get和post请求
    sql分组取最大值
    解析xml
    jsp:include
    schema的详解2
    文法和语言
    高级语言程序简介
    Dataframe根据某一列的值获取满足条件的行的其他列的值
    Dataframe数值转为二维列表
  • 原文地址:https://www.cnblogs.com/yedushusheng/p/5524074.html
Copyright © 2020-2023  润新知