之前写的桶排序有点问题,上一篇删掉,这次重新写一下(文中除了文末划掉的就是修改的地方)
前一天写的是计数排序,今天写的是计数排序的超进化——桶排序。
桶排序: 将数组分到有限数量的桶子里,每一个桶都是它利用了函数的映射关系而得到的,每个桶子再个别排序,最后把所有的桶合并就得到了排完序后的数组。
还是以 a = {9, 3, 5, 4, 9, 1, 2, 7, 8,1,3, 6, 5, 3, 4, 0, 10, 9, 7, 9} 为例子,在计数排序中,我们创建了一个 b[11]来计数。按照桶排序的思想,此时这个长度为11的数组就是11个桶,将满足条件的a中元素放到对应的桶中,然后每个桶中分别排序(此时每个桶中只存在一种元素,因此这一步不需要),之后把已经排序好的桶合并,得到的就是排序后的数组。
图例算法示意:
来一个实际应用: 在一个文件中有10G个整数,乱序排列,要求找出中位数。内存限制为2G。
首先抓住三点
1、一个整数是4byte (4byte=32bit)
2、通过字节比较大小,从最高位开始逐位比较。
3、排序完成后的整数组,如果此时个数为偶数则中位数是 N/2 个整数和 N/2+1 个整数的平均数;如果此时个数为奇数 则中位数是 (N+1)/2 ,10G的整数是偶数个,所以中位数是第5G+第(5G+1)个整数的平均数。
思路:
1、 每次取2G的数据,也就是 n =(2 ^ 30)/4个整数,将这n个整数取其高8位(32-25),分成(2 ^8 -1 =255) 桶,将这2G的数据放到对应的桶中,
用255个整形的空间分别存储这255个桶里面对应整数的数量。按照这个步骤将10G的数据都处理完。(整形的长度是2 ^ 32 > (2 ^ 30)/4*10 ,所以整形的空间一定足够存放)
分析:接下来只要从上述的4个255的桶中找到第5G+第(5G+4byte)/4 个整数
Count:累计整数数量
index:当前桶的索引
a:第5G个整数
b:第(5G+4byte)/4 个整数
2、 找到一个最小的index使得 (1 ~ index) 桶内整数数量 > (5G+4byte)/4
此时,a,b只会出现
①在 index个桶 或者
②分别在index-1、index这两个桶。
3、 将index 或者 index-1、index 这两个桶的整数取出来,此时如果桶内整数数量少,进行快排找到中位数
① n = ((5G+4byte)/4) - ((1~index-1)桶内整数个数) 这个n所在位置的值就是a的值,因此b就是下一个
②a = 第(index-1)桶 快排之后最后一个数;b=第(index)桶 快排之后的第一个数
即可;如果桶内数量多则可以重复上述思想继续对(24-17)、(16-9)、(8-1)进行桶排序,方可找到 a和b
如果方法有误,或者其他好方法,欢迎私聊 谢谢! ^ V ^