IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 基数排序的基本思想与模板分析【排序算法篇】 -> 正文阅读

[数据结构与算法]基数排序的基本思想与模板分析【排序算法篇】

基本思想

假如来了一个混乱数组org,我们需要将它排好序。我们做如下操作。

  1. 先得到该数组中最大的那个数MAX。
  2. 创建一个数组ans,该数组的长度就是MAX。
  3. 接下来遍历混乱数组organs[org[i]]=org[i];

以上的操作很简单,我们可以轻易的看出其缺点就是太浪费空间。
那么基数排序,则是对以上操作进行了优化。基数排序我们做如下操作。

  1. 创建桶数组,其长度为20(考虑正负数)。
  2. 接下来循环,第一轮是取每个数字的个位数,在桶数组对应位置+1。
  3. 根据桶的个数生成位置。
  4. 获取位置,更新原数组。
  5. 第二轮循环开始,这次是取每个数字的百位数,重复以上操作。
  6. 接下来依次类推,循环次数为原数组最大值的位数。

图示

以下动图取自网络
在这里插入图片描述

代码模板

public void get() {
    int[] arr = new int[]{17, -13, 20, -7, 2, 17, 12};

    radixSort(arr);

    for (int i : arr) {
        System.out.println(i);
    }
}


/**
 * 基数排序(升序)
 * @param arr 原数组
 */
public void radixSort(int[] arr) {

    //辅助数组
    int[] tmp = new int[arr.length];
    //基数
    int n = 1;
    //初始化桶数组。位置【0~9】存放0~9,位置【11~19】存放-1~-9
    int[] bin = new int[20];
    while (true) {

        /**
         * 该for循环将根据基数,确定原数组每个数字对应位置,在该位置上添加一个桶(表示存放该数字)
         * 如在第一轮while循环中基数n是1,则取个位上的数字进行桶计算,原数组有17这个数字,则在7号桶上+1。
         * 在本次案例{17, -13, 20, -7, 2, 17, 12}中,
         *      第一轮while循环中,该for循环结束时:bin={1,0,2,0,0,0,0,2,0,0,0,0,0,1,0,0,0,1,0,0}
         */
        for (int val : arr) {
            int j = (val / n) % 10;//得到该数字在桶数组中的位置
            //以下对正负数的位置区间进行确定,位置【0~9】存放0~9,位置【11~19】存放-1~-9
            if (j >= 0) {
                bin[j]++;//在对应位置上+1,表示该数字在该位置占一位的空间
            } else {
                bin[10 - j]++;
            }
        }

        //当所有的数字全都在‘0’号桶中,意味着原数组中的数字没有比基数还大的,基数排序到此结束,退出循环。
        if (bin[0] == arr.length) break;

        /**
         * 接下来我们根据桶的个数,生成位置
         * 我们将考虑正数与负数(在这个案例中,我们将0看作正数)
         * 
         * 我们先对负数的桶位置进行计算,位置【11~19】存放-1~-9,
         *      因为是升序,所以越小的数占据越前的位置。bin[i]修改为:当前数值+bin[i+1]。
         * 接下来对正数的桶位置进行计算,bin[i]修改为:当前数值+bin[i-1]。
         * 
         * 以下两个循环结束后,bin={3,3,5,5,5,5,5,7,7,7,0,0,0,1,1,1,1,2,2,2}
         */
        for (int i = 18; i > 10; i--) {
            bin[i] += bin[i + 1];
        }
        bin[0]+=bin[11];
        for (int i = 1; i < 10; i++) {
            bin[i] += bin[i - 1];
        }

        //获取位置,在辅助数组中在bin[j]位置上存入数字
        for (int i = tmp.length - 1; i >= 0; i--) {
            int j = (arr[i] / n) % 10;
            if (j >= 0) {
                bin[j]--;
                tmp[bin[j]] = arr[i];
            } else {
                bin[10 - j]--;
                tmp[bin[10 - j]] = arr[i];
            }
        }

        //更新原数组
        System.arraycopy(tmp, 0, arr, 0, tmp.length);

        //基数每轮提升一个数量级,如1->10->100...
        n *= 10;

        //清空桶,以便下次存放
        Arrays.fill(bin, 0);
    }
}
  • 时 间 复 杂 度 为 O ( d ( n + r ) ) , 空 间 复 杂 度 为 O ( n ) 时间复杂度为O(d(n+r)),空间复杂度为O(n) O(d(n+r))O(n)
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:25:59  更:2021-10-26 12:26:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:51:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码