一、基本思想
桶排序是将待排序的数据分割成许多buckets,然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法。也是典型的分而治之(divide-and-conquer)的策略。
 
二、算法过程及PHP代码实现
1)找出待排序数组arr中的最大值max、最小值min;
2)设置一个定量的数组当作空桶,范围为min~max(min、max为步骤1求得的最小值、最大值);
3)遍历待排序数组arr,计算每个元素arr[i]放的桶,把数据放到对应的桶里;
4)如果桶不为空,对桶中的数据进行排序;
5)遍历桶数组,把所有桶中排序好的元素放到一个新的数组里。
例如:
待排序数组为5,3,5,2,8,其最小值是2,最大值是8,可以在2-8的取值范围内定义一个桶数组$bucket,并且让所有的元素值都为0;
对需要排序的数组进行循环遍历,将数据依次放到对应的桶中,即:
首先是5,则使$bucket[5]++,继续遍历,$bucket[2]=1,$bucket[3]=1,$bucket[5]=2,$bucket[8]=1,
然后循环$bucket数组,若$bucket[2]=1,则循环输出元素2一次,$arr[5]=2,则循环输出5两次,结果为 2 3 5 5 8
PHP代码如下:
<?php
function bucketSort($arr) {
    // 设置木桶
    $bucket = [];
    $min = min($arr);
    $max = max($arr);
    // $bucket = array_fill($min, $max - $min + 1, 0);
    for ($m = $min; $m <= $max; $m++) {
        $bucket[$m] = 0;
    }
    // 将待排数据按照范围放到对应的木桶中
    $cnt = count($arr);
    for ($n = 0; $n < $cnt; $n++) {
        $bucket[$arr[$n]]++;
    }
    // 从木桶中拿出数据
    $result = [];
    for ($i = $min; $i <= $max; $i++) {
        if (($bucket[$i]) > 0) {
            for ($j = 1; $j <= $bucket[$i]; $j++) {
                $result[] = [$i];
            }
        }
    }
    // 处理数组
    $res = [];
    foreach ($result as $v) {
        $res[] = $v[0];
    }
    return $res;
}
 
, 96];
$res = bucketSort($arr);
print_r($res);
设置木桶也可以先确定木桶的个数,即n = (max - min) / arr.length + 1,其中,max、min为待排序数组的最大值、最小值,然后桶的范围为0-(n-1),后面的步骤同前面的3-5步相同。
PHP代码如下:
<?php
function bucketSort(&$arr) {
    $min = min($arr);
    $max = max($arr);
    $n = $max - $min + 1;
    $buckets = [];
    for ($i = 0; $i < $n; $i++) {
        $buckets[$i] = 0;
    }
    for ($i = 0; $i < count($arr); $i++) {
        $buckets[$arr[$i] - $min]++;
    }
    $k = 0;
    for ($i = 0; $i < $n; $i++) {
        while ($buckets[$i]-- > 0) {
            $arr[$k++] = $i + $min;
        }
    }
}
 
三、效率分析
对于N个待排数据,M个桶,
1、时间复杂度:O(N+C),其中C=N*(logN-logM)
2、空间复杂度:O(N+M),稳定性排序
3、缺陷:
1)参与排序的数组存放的必须是整数。
2)数组中的最大数和最小数保持在一个合理的间距内。
3)需要额外的内存空间。
 
四、算法改进
按着上述代码,如果要排序的范围是1-100万,将申请大量的内存,也就是设置了100万个桶。为了节省内存,可以改进这个算法,把待排序数组划分为n个大小相同的子区间(桶),然后基于某种映射函数,将待排序序列的元素映射到第i个桶中,再对每个桶中的所有元素排序,最后合并。
1)确定元素的最大值max、最小值min、数组长度length;
2)确定桶数:n = (max - min) / length + 1;
3)确定桶的编号:0 ~ (n - 1);
4)确定数组元素对应的桶的编号:index = (x - min) / length;
5)对每个桶进行排序;
6)合并所有桶的元素。
PHP代码如下:
<?php
function bucketSort($arr) {
    $length = count($arr);
    $min = min($arr);
    $max = max($arr);
    $n = ceil(($max - $min) / $length) + 1;
    // 设置木桶
    $buckets = [];
    for ($i = 0; $i < $n; $i++) {
        $buckets[$i] = [];
    }
    // 将每个元素放入桶
    for ($i = 0; $i < $length; $i++) {
        $index = ceil(($arr[$i] - $min) / $length);
        $buckets[$index][] = $arr[$i];
    }
    // 对每个桶进行排序
    $res = [];
    for ($i = 0; $i < $n; $i++) {
        sort($buckets[$i]);
        // 合并所有桶中的元素
        $res = array_merge($res, $buckets[$i]);
    }
    return $res;
}
$arr = [12, 31, 85, 7, 41, 34, 10, 96];
$res = bucketSort($arr);
print_r($res);
这种方法,只需要设置12个桶即可,大大的节省了空间。

数据结构与算法之PHP排序算法(桶排序)的更多相关文章

  1. 算法笔记(c++)--桶排序题目

    算法笔记(c++)--桶排序 记得题目是排序,输入n个1-1000的数字然后去重然后排序. 桶排序没毛病 #include<iostream> using namespace std; i ...

  2. 计数排序和桶排序(Java实现)

    目录 比较和非比较的区别 计数排序 计数排序适用数据范围 过程分析 桶排序 网络流传桶排序算法勘误 桶排序适用数据范围 过程分析 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比 ...

  3. 计数排序与桶排序python实现

    计数排序与桶排序python实现 计数排序 计数排序原理: 找到给定序列的最小值与最大值 创建一个长度为最大值-最小值+1的数组,初始化都为0 然后遍历原序列,并为数组中索引为当前值-最小值的值+1 ...

  4. 【JS面试向】选择排序、桶排序、冒泡排序和快速排序简介

    新年伊始,又到了金三银四的时候了.面对前端越来越多的算法面试题,我简单的整理了一下几种比较常见的数组排序方式,分别介绍其基本原理和优劣势.(ps:才疏学浅,希望大家可以在issues下面指出问题) 选 ...

  5. 计数排序与桶排序(bucket sort)

    Bucket Sort is a sorting method that subdivides the given data into various buckets depending on cer ...

  6. 计数排序、桶排序python实现

    计数排序在输入n个0到k之间的整数时,时间复杂度最好情况下为O(n+k),最坏情况下为O(n+k),平均情况为O(n+k),空间复杂度为O(n+k),计数排序是稳定的排序. 桶排序在输入N个数据有M个 ...

  7. Java基础知识强化51:经典排序之桶排序(BucketSort)

    1. 首先说明三点: (1)桶排序是稳定的 (2)桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 (3)桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 2. 桶排序的分析 ...

  8. java-数组排序--计数排序、桶排序、基数排序

    计数排序引入 不难发现不论是冒泡排序还是插入排序,其排序方法都是通过对每一个数进行两两比较进行排序的,这种方法称为比较排序,实际上对每个数的两两比较严重影响了其效率,理论上比较排序时间复杂度的最低下限 ...

  9. 排序基础之非比较的计数排序、桶排序、基数排序(Java实现)

    转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/6639353.html  比较和非比较排序 快速排序.归并排序.堆排序.冒泡排序等比较排序,每个数都必须和其他 ...

  10. 排序:桶排序Bucket sort

    补充说明三点 1,桶排序是稳定的 2,桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 3,桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 无序数组有个要求,就是成员隶属于 ...

随机推荐

  1. 博客系统(cnblog)

    1.用户表:Userinfo 2.博客站点表:Blog 3.标签表:Tag 4.分类表:Category 5.文章表:Article 6.点赞踩表:ArticelUpDown 7.评论表:Commen ...

  2. turtle画王思聪吃热狗(杨艳春,何金凝小组)

    点击此处查看视频:http://v.douyin.com/RCY8GD/import turtle as t t.setup(450,300) t.pensize(4) t.color('black' ...

  3. tomcat部署项目

    提示:指定jdk版本  在bin路径下的setclasspath.bat文件添加 set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_201 set JRE_HO ...

  4. C# 多笔数据导入DB

    6万笔数据瞬间导入进DB 命名空间 using NPOI.HSSF.UserModel; using NPOI.XSSF.UserModel; //Filename为文件路径 public JsonR ...

  5. 基于Java服务的前后端分离解决跨域问题

    导语:解决跨域问题,前后端都增加相应的允许跨域的代码段即可. 一.后端增加允许跨域的代码,可以在具体controler层加,最好是在filter中添加,这样添加一次就够了,不用在每个controler ...

  6. js中的排序方法

    一.冒泡排序 var  arr=[22,1,33,19,77]; function  bubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ for( ...

  7. c语言#define用法

    01 作用域 预编译作用域限本文全局,如: a.c中定义:#define TEST 1 b.c中定义:#define TEST 2 两者编译不交叉,互不影响. 若需#define TEST作用于a.c ...

  8. day17

    包什么是包 包的本质是文件夹为什么使用包 函数可以使得同一个文件中代码结构更清晰 木块(py文件)是以文件形式来组织代码结构 如果文件越来越多管理起来也不方便,所以需要使用文件夹来管理.从文件夹级别来 ...

  9. 基于卷积神经网络CNN的电影推荐系统

    本项目使用文本卷积神经网络,并使用MovieLens数据集完成电影推荐的任务. 推荐系统在日常的网络应用中无处不在,比如网上购物.网上买书.新闻app.社交网络.音乐网站.电影网站等等等等,有人的地方 ...

  10. mysql学习(一)

    mysql学习,这篇博文是关于目前市面上火热的关系型数据库mysql的学习记录. 1,关于mysql的安装,自行百度. 2,sql:structure query language 结构化查询语言. ...