排序算法-基数排序

排序算法-基数排序

<?php
/**
 * php算法实战.
 *
 * 排序算法-基数排序
 *
 * 分为两种LSD,MSD
 *
 * LSD:
 * 从个位开始,把当前位的数放到0~9对应的桶子中,直到最高位为止
 * 适合位数较短
 *
 * MSD:
 * 从最高位开始,不立即合并,再在桶中以下一位建立子桶,直到建立了最低位桶为止
 * 适合位数较多
 */
/**
 * 基数排序
 *
 * Least Significant Digit first
 *
 * 最低位优先排序
 *
 * @param array $value 待排序数组
 *
 * @return array
 */
function radix_lsd(&$value = []) {
    // 获取序列值最大位数
    $max = 0;
    foreach ($value as $v) {
        $length = strlen((string)$v);
        if ($length > $max) {
            $max = $length; // 更新
        }
    }
    unset($v);
    $splice = 1; // 取最小位 初始从右往左数第一位
    while ($splice <= $max) {
        // 分配数字到桶中
        for ($i = 0;$i < 10;$i++) {
            foreach ($value as $k => $v) {
                $length = strlen((string)$v);
                // 当前位索引位置
                $index = $length - $splice;
                // 不存在该位 则认为为0
                if ($index < 0) {
                    if ($i === 0) {
                        $arr[0][] = $v;
                    }
                    continue;
                }
                $aaa = ((string)$v) [$index];
                if (((string)$v) [$index] === (string)$i) {
                    $arr[$i][] = $v;
                }
            }
            unset($v);
        }
        // 合并桶中数字
        unset($value);
        foreach ($arr as $tmp) {
            foreach ($tmp as $v) {
                $value[] = $v;
            }
        }
        unset($tmp);
        unset($v);
        unset($arr);
        ++$splice;
    }
    return $value;
}
/**
 * 基数排序
 *
 * Most Significant Digit first
 *
 * 最高位优先排序
 *
 * @param array $value 待排序数组
 * @param integer $max 序列最大位数
 *
 * @return array
 */
function radix_msd(&$value = [], $max = 0, $max_origin = 0, $length_origin = 0, &$origin = [], $key = 0) {
    if ($max < 1) {
        return;
    }
    // 按最高位分组,不存在当前位则认为0
    $arr = [];
    for ($i = 0;$i < 10;$i++) {
        foreach ($value as $v) {
            $length = strlen((string)$v);
            $index = $length - $max;
            if ($index < 0) {
                if ($i === 0) {
                    $arr[0][] = $v;
                }
                continue;
            }
            if (((string)$v) [$index] === (string)$i) {
                $arr[$i][] = $v;
            }
        }
        unset($v);
    }
    unset($i);
    --$max;
    if (!empty($origin)) {
        $origin[$key] = $arr;
    } else {
        $value = $arr;
    }
    foreach ($value as $k => & $v) {
        radix_msd($v, $max, $max_origin, $length_origin, $value, $k);
    }
    if ($max < $max_origin - 1) {
        return;
    }
    // 重新拼接
    return get_value($value, $length_origin);
}
/**
 * 合并排序
 *
 * 合并最后按个位排序完成的值
 *
 * @param  [type]  $value  排序后值
 * @param  integer $length 原始数组长度
 * @param  array  $result 存放排序后数的新空间
 * @return array          排序后数组
 */
function get_value($value = [], $length = 0, &$result = []) {
    if (count($result) === $length) {
        return;
    }
    foreach ($value as $k => $v) {
        if (is_array($v)) {
            get_value($v, $length, $result);
            continue;
        }
        $result[] = $v;
    }
    return $result;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券