排序算法四(桶排序)

一、桶排序算法的引入。

  之前我们已经说过了计数排序的算法。

  这个时候我们如果有这样的一个待排序数据序列:

int  x[14]={-10, 2, 3, 7, 20, 23, 25, 40, 41, 43,60, 80, 90, 100};

  我们如果按照计数排序的算法,那么待排序数据的范围是:-10 到 100

  我们为了实现对于这个数据集的遍历,这个时候需要额外的开辟一个大小为(100- (-10)+ 1)的空间,这个时候的空间复杂度达远远超过我们的预计,也就是这个造成了空间的浪费。

  所以我们可以说,计数排序还存在一个缺点:即数据里面的max 和min 的差值相比于待排序数据的数目来说,不能过大,否则会造成空间的浪费

  桶排序算法相当于做了一个对于计数排序算法做了一个升级。

  只不过计数排序算法计数是对于每一个排序数字进行的,而桶排序算法则将这个范围放宽,变成了一个范围。

二、桶排序算法的过程。

  1、比如对于上面的一个待排序数据,我们需要把它划分为一系列的范围,从min 到 min,这就相当于有了一个一个的“桶”。

  2、对应的范围的数据放入对应范围的桶里面。

  3、然后对于每一个范围的数据采用其他的排序算法进行排序,使得每一个桶内部的数据都是有序的,移动到已经有序的数据集中。

  上面有两个步骤比较关键:

  第一个是对于桶的范围的划分,这需要一个映射的规则,如果我们把桶划分的较小,这个时候几乎每一个数据都是一个桶;了,空间浪费。如果划分的太大,所有的数据都到了一个桶里面去,相当于没有划分。

  第二个是每一个桶的内部的排序算法的选择,这个影响最后总体的桶排序算法的稳定性。

三、例子

  对于上面的一个待排序数据,这个时候我们已经知道了max=100, min=-10.

  随后我们设计一个映射的规则,比如设计一个规则,使得 -10到 50 分为一个桶,50到100分为一个桶。

  我们可以设计这样的一个规则:

  ƒ(x)=x/30 - min/30

  这样我们就可以把上面的数组分成了四组:

根据结果分组 数据
0 -10, 2, 3, 7
1 20, 23 ,25 ,40, 41
2 60
3 80,  90, 100

  然后就可与根据分组分别进行排序。

四、算法

/*算法:桶排序C++版本*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std;
 //这个算法的作用是对于数组A中位于位置A[l]到A[h]中的元素分为size个桶去排序
void bksort(float A[],int l,int h,int size){
    vector<float> b[size];//有size个数据,就分配size个桶
    int min=A[l];
    for(int i=l;i<=h;i++){//便利得到最小值
      if(A[i]<min)
           min=A[i];
    }
    for(int i=l;i<=h;i++){
        int bi = (A[i]-min)/size;//元素A[i]的桶编号,这里修改映射规则
        b[bi].push_back(A[i]);//将元素A[i]压入桶中
    }
    for(int i=0;i<size;i++)
        sort(b[i].begin(),b[i].end());//桶内排序
    int idx = l;//指向数组A的下标
    for(int i=0;i<size;i++){//遍历桶
        for(int j=0;j<b[i].size();j++){//遍历桶内元素
            A[idx++] = b[i][j];
        }
    }
}

int main(){
    float A[] = {0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68};
    bksort(A,2,9,3);
    for(int i=0;i<10;i++)
        cout<<A[i]<<" ";
}

五、复杂度分析

  复杂度主要是取决于排序算法。

  如果排序算法是快速排序,则可以达到Θ( n ) (大佬们的计算结果)

六、参考链接:

  复杂度计算看这个:https://blog.csdn.net/bqw18744018044/article/details/81738883

  算法的过程描述借鉴的是这个:https://www.jianshu.com/p/204ed43aec0c

  

原文地址:https://www.cnblogs.com/fantianliang/p/11881381.html

时间: 2024-10-04 04:48:06

排序算法四(桶排序)的相关文章

最快最简单的排序算法:桶排序

在我们生活的这个世界中到处都是被排序过的.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东西都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎考的真是惨不忍睹(满分是10分).接下来将分数进行从大到小排序,排序后是8

排序算法之——桶排序

这是本人的第一篇随笔,为的是分享学习经验,和大家讨论一些算法,以便取得些许进步,也是对学习的总结. 话不多说,下面我会用图文的方式向各位介绍桶排序. 1.主要思想: 桶排序的大体思路就是先将数组分到有限个桶中,再对每个桶中的数据进行排序,可以说是鸽巢排序的一种归纳结果(对每个桶中数据的排序可以是桶排序的递归,或其他算法,在桶中数据较少的时候用插入排序最为理想). 2.算法效率: 对N个数据进行桶排序的时间复杂度分为两部分: 1.对每一个数据进行映射函数的计算(映射函数确定了数据将被分到哪个桶),

排序算法下——桶排序、计数排序和基数排序

桶排序.计数排序和基数排序这三种算法的时间复杂度都为 $O(n)$,因此,它们也被叫作线性排序(Linear Sort).之所以能做到线性,是因为这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作. 1. 桶排序(Bucket Sort)? 1.1. 桶排序原理 桶排序,顾名思义,要用到"桶".核心思想是将要排序的数据分到几个有序的桶里,每个桶的数据再单独进行排序.桶内排完序后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了. 1.2. 桶排序的时间复杂度分析 如

排序算法 之 桶排序

桶排序是一种效率很高的排序算法,它的时间复杂度为O(n),但桶排序有一定的限制,只有当待排序序列的元素为0到某一确定取值范围的整数时才适用,典型的例子比如成绩的排序等. 算法思想: 设待排序序列的元素取值范围为0到m,则我们新建一个大小为m+1的临时数组并把初始值都设为0,遍历待排序序列,把待排序序列中元素的值作为临时数组的下标,找出临时数组中对应该下标的元素使之+1:然后遍历临时数组,把临时数组中元素大于0的下标作为值按次序依次填入待排序数组,元素的值作为重复填入该下标的次数,遍历完成则排序结

排序算法之桶排序

一.原理 桶排序是计数排序的升级版,如果计数排序中数的范围比较大呢?之前的计数排序数字范围是1-200,假如1-20000呢?利用桶排序就可以对其进行优化. 步骤: (1)将元素分在不同的桶中 (2)在对每一个桶中的元素进行排序 桶排序的的快慢取决于数据的分布: 当输入的数据可以均匀的分配到每一个桶中,排序最快 当输入的数据被分配到了同一个桶中,排序最慢 关键点: 每一个桶中有多少个数 每一个数应该放到哪一个桶中 二.实现 def binSort(li,min_num,max_num,bin_n

排序算法&lt;四&gt;希尔排序

#include<iostream> using namespace std; int arr[]={11,12,51,23,64,23,68,1,12}; void shellsort1(int arr[]) { int i, j, gap; for (gap = 9 / 2; gap > 0; gap /= 2) //步长 for (i = 0; i < gap; i++) { //直接插入排序 for (j = i + gap; j < 9; j += gap) if

排序算法四:交换排序之冒泡排序

排序算法四:交换排序之冒泡排序 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 引言 在我的博文<"主宰世界"的10种算法短评>中给出的首个算法就是高效的排序算法.本文将对排序算法做一个全面的梳理,从最简单的"冒泡"到高效的堆排序等. 系列博文的前三篇讲述了插入排序的三种不同类型,本文讲述第二大类的排序算法:交换排序,包括冒泡排序和快速排序. 排序相关的的基本概念 排序:将一组杂乱无章的数据按一定的规律顺次排列起

经典排序算法 - 鸽巢排序Pigeonhole sort

经典排序算法 - 鸽巢排序Pigeonhole sort 原理类似桶排序,同样需要一个很大的鸽巢[桶排序里管这个叫桶,名字无所谓了] 鸽巢其实就是数组啦,数组的索引位置就表示值,该索引位置的值表示出现次数,如果全部为1次或0次那就是桶排序 例如 var pigeonHole = new int[100]; pigeonHole[0]的值表示0的出现次数... pigeonHole[1]的值表示1的出现次数... pigeonHole[2]的值表示2的出现次数... 参考http://hi.bai

排序算法之希尔排序

文章转载自http://www.cnblogs.com/chengxiao/ 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一.本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组