node 桶排序

实现思路与步骤

思路

  1. 设置固定空桶数
  2. 将数据放到对应的空桶中
  3. 将每个不为空的桶进行排序
  4. 拼接不为空的桶中的数据,得到结果

步骤演示

假设一组数据(20长度)为

[63,157,189,51,101,47,141,121,157,156,194,117,98,139,67,133,181,13,28,109] 

现在需要按5个分桶,进行桶排序,实现步骤如下:

  1. 找到数组中的最大值194和最小值13,然后根据桶数为5,计算出每个桶中的数据范围为(194-13+1)/5=36.4

  2. 遍历原始数据,(以第一个数据63为例)先找到该数据对应的桶序列Math.floor(63 - 13) / 36.4) =1,然后将该数据放入序列为1的桶中(从0开始算)
  3. 当向同一个序列的桶中第二次插入数据时,判断桶中已存在的数字与新插入的数字的大小,按从左到右,从小打大的顺序插入。如第一个桶已经有了63,再插入51,67后,桶中的排序为(51,63,67) 一般通过链表来存放桶中数据,但js中可以使用数组来模拟
  4. 全部数据装桶完毕后,按序列,从小到大合并所有非空的桶(如0,1,2,3,4桶)
  5. 合并完之后就是已经排完序的数据

步骤图示

实现代码

JS实现代码(数组替代链表版本)

var bucketSort = function(arr, bucketCount) {
    if (arr.length <= 1) {
        return arr;
    }
    bucketCount = bucketCount || 10;
    //初始化桶
    var len = arr.length,
    buckets = [],
    result = [],
    max = arr[0],
    min = arr[0];
    for (var i = 1; i < len; i++) {
        min = min <= arr[i] ? min: arr[i];
        max = max >= arr[i] ? max: arr[i];
    }
    //求出每一个桶的数值范围
    var space = (max - min + 1) / bucketCount;
    //将数值装入桶中
    for (var i = 0; i < len; i++) {
        //找到相应的桶序列
        var index = Math.floor((arr[i] - min) / space);
        //判断是否桶中已经有数值
        if (buckets[index]) {
            //数组从小到大排列
            var bucket = buckets[index];
            var k = bucket.length - 1;
            while (k >= 0 && buckets[index][k] > arr[i]) {
                buckets[index][k + 1] = buckets[index][k];
                k--
            }
            buckets[index][k + 1] = arr[i];
        } else {
            //新增数值入桶,暂时用数组模拟链表
            buckets[index] = [];
            buckets[index].push(arr[i]);
        }
    }
    //开始合并数组
    var n = 0;
    while (n < bucketCount) {
        if (buckets[n]) {
            result = result.concat(buckets[n]);
        }
        n++;
    }
    return result;
};
//开始排序
arr = bucketSort(arr, self.bucketCount);

JS实现代码(模拟链表实现版本)

var L = require('linklist'); //链表
var sort = function(arr, bucketCount) {
    if(arr.length <= 1) {
        return arr;
    }
    bucketCount = bucketCount || 10;
    //初始化桶
    var len = arr.length,
        buckets = [],
        result = [],
        max = arr[0],
        min = arr[0];
    for(var i = 1; i < len; i++) {
        min = min <= arr[i] ? min : arr[i];
        max = max >= arr[i] ? max : arr[i];
    }
    //求出每一个桶的数值范围
    var space = (max - min + 1) / bucketCount;
    //将数值装入桶中
    for(var i = 0; i < len; i++) {
        //找到相应的桶序列
        var index = Math.floor((arr[i] - min) / space);
        //判断是否桶中已经有数值
        if(buckets[index]) {
            //数组从小到大排列
            var bucket = buckets[index];
            var insert = false; //插入标石
            L.reTraversal(bucket, function(item, done) {
                if(arr[i] <= item.v) { //小于,左边插入
                    L.append(item, _val(arr[i]));
                    insert = true;
                    done(); //退出遍历
                }
            });
            if(!insert) { //大于,右边插入
                L.append(bucket, _val(arr[i]));
            }
        } else {
            var bucket = L.init();
            L.append(bucket, _val(arr[i]));
            buckets[index] = bucket; //链表实现
        }
    }
    //开始合并数组
    for(var i = 0, j = 0; i < bucketCount; i++) {
        L.reTraversal(buckets[i], function(item) {
            // console.log(i+":"+item.v);
            result[j++] = item.v;
        });
    }
    return result;
};
 
//链表存储对象
function _val(v) {
    return {
        v: v
    }
}
//开始排序
arr = bucketSort(arr, self.bucketCount);

其中,linklist为引用的第三方库,地址
linklist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
桶排序是一种线性排序算法,基本思路是将待排序数据分到有限数量的中,然后对每个进行排序,最后按照顺序把所有的数据依次取出来。 具体实现流程如下: 1. 确定待排序数据的最大值和最小值 2. 根据最大值和最小值确定的数量和的范围:数量 =(数据的范围 / 的数量)+ 1 3. 将数据依次放入对应的中 4. 对每个中的数据进行排序,可以使用其他排序算法,例如插入排序 5. 将所有中的数据依次取出,组成有序序列 下面是一个简单的 C 语言桶排序实现代码: #include <stdio.h> #include <stdlib.h> typedef struct bucket_node { int val; struct bucket_node *next; } bucket_node; void bucket_sort(int *arr, int n) { if (n <= 1) { return; } // 确定最大值和最小值 int max_val = arr[0]; int min_val = arr[0]; for (int i = 0; i < n; ++i) { if (arr[i] > max_val) { max_val = arr[i]; } if (arr[i] < min_val) { min_val = arr[i]; } } // 计算的数量和范围 int bucket_count = (max_val - min_val) / 10 + 1; bucket_node **buckets = (bucket_node **)malloc(bucket_count * sizeof(bucket_node *)); for (int i = 0; i < bucket_count; ++i) { buckets[i] = NULL; } // 将数据放入对应的中 for (int i = 0; i < n; ++i) { int bucket_idx = (arr[i] - min_val) / 10; bucket_node *node = (bucket_node *)malloc(sizeof(bucket_node)); node->val = arr[i]; node->next = buckets[bucket_idx]; buckets[bucket_idx] = node; } // 对每个中的数据进行排序 int idx = 0; for (int i = 0; i < bucket_count; ++i) { bucket_node *node = buckets[i]; while (node != NULL) { arr[idx++] = node->val; node = node->next; } } // 释放内存 for (int i = 0; i < bucket_count; ++i) { bucket_node *node = buckets[i]; while (node != NULL) { bucket_node *tmp = node; node = node->next; free(tmp); } } free(buckets); } int main() { int arr[] = {5, 3, 6, 2, 1, 7, 9, 8, 4}; int n = sizeof(arr) / sizeof(arr[0]); bucket_sort(arr, n); printf("排序后的数组:"); for (int i = 0; i < n; ++i) { printf("%d ", arr[i]); } printf("\n"); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值