Java玩转《啊哈算法》排序之桶排序

过去心不可得,现在心不可得,未来心不可得

目录在这里

  • 楔子
  • 代码地址
  • 桶排序
  • 代码
    • 核心部分
      • 优缺点
    • 完整代码
    • 演示
  • 升级版
    • 核心代码
    • 完整代码
    • 演示

楔子

大家好!本人最近看了下《啊哈算法》,写的确实不错,生动形象又有趣(我没收钱,确实如此 )。

但对我来说,稍显遗憾的是,书籍代码是c语言,而不是本人常用的Java。

那就弥补遗憾,说干就干,把这本书的示例语言用java给翻译一遍!!!

于是就有了本篇博客,当然这只是第一篇,主要是讲解桶排序。
在这里插入图片描述

没有买纸质书的童鞋也甭担心,电子版的下载链接已经放到下方了,自己下载去吧!!!

链接:https://pan.baidu.com/s/1imxiElcCorw2F-HJEnB-PA?pwd=jmgs
提取码:jmgs

不过还是建议有条件的同学可以买下纸质书,尊重一下作者的劳动成果。

代码地址

本文代码已开源:

git clone https://gitee.com/guqueyue/my-blog-demo.git

请切换到gitee分支,

然后查看aHaAlgorithm模块下的src/main/java/com/guqueyue/aHaAlgorithm/chapter_1_Sort即可!

桶排序

算法学习千千万,排序是块敲门砖!!!

国内算法学习似乎有个不成文的规定,想学算法,先学排序。而桶排序可以说是排序算法中最简单的算法了。

在这里插入图片描述

桶排序的核心原理非常简单:

遍历需要排序的元素集合,用一个数组表示。数组的一个个连续的空间作为一个个桶,索引为元素,而索引对应的值为元素个数。

相当于把元素放到对应的一个一个桶里面,所以叫桶排序。
在这里插入图片描述

而因为数组的索引是连续的,所以遍历数组索引就能得到一个升序的元素集合。如果索引对应的值为0,说明该元素不存在。

代码

核心部分

	/**
     * @Description 桶排序
     * @Param [scoreArr]
     * @return int[]
     **/
    private static int[] bucketSort(int[] scoreArr) {

        // 11为数据范围的大小
        int[] bucket = new int[11];
        // 用于返回排序后的数组
        int[] result = new int[scoreArr.length];

        // 入桶,计数
        for (int num : scoreArr) {
            bucket[num]++;
        }

        // 根据桶的索引以及计数的次数,生成排序后的数组 - 如果需要降序,倒序遍历数组即可
        int k = 0;
        for (int i = 0; i < bucket.length; i++) { // 遍历每个桶
            for (int j = 0; j < bucket[i]; j++) { // 遍历桶里面的元素
                result[k++] = i;
            }
        }

        return result;
    }

优缺点

通过上文的讲解以及核心代码,我们不难得出桶排序具有以下的优缺点:

  • 优点:
    1. 简单
    2. 速度快。时间复杂度为:O(m+n), 其中m为排序数组的长度,n为桶的长度。
  • 缺点:
    1. 占用空间。空间复杂度为O(m+n),因为桶的长度取决于元素取值范围,元素取值范围越大,越占用空间。
    2. 有使用局限,只能对整数进行排序。若元素中存在小数无法使用桶排序,因为数组的索引不能为小数。

完整代码

package com.guqueyue.aHaAlgorithm.chapter_1_Sort;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @Author: guqueyue
 * @Description: 桶排序
 * @Date: 2024/1/8
 **/
public class BucketSort {

    public static void main(String[] args) {

        // 获取分数数组
        int[] scoreArr = getScoreArr();
        System.out.println("输入的数组为: " + Arrays.toString(scoreArr));

        // 桶排序
        int[] result = bucketSort(scoreArr);
        System.out.println("排序后:" + Arrays.toString(result));
    }

    /**
     * @Description 桶排序
     * @Param [scoreArr]
     * @return int[]
     **/
    private static int[] bucketSort(int[] scoreArr) {

        // 11为数据范围的大小
        int[] bucket = new int[11];
        // 用于返回排序后的数组
        int[] result = new int[scoreArr.length];

        // 入桶,计数
        for (int num : scoreArr) {
            bucket[num]++;
        }

        // 根据桶的索引以及计数的次数,生成排序后的数组 - 如果需要降序,倒序遍历数组即可
        int k = 0;
        for (int i = 0; i < bucket.length; i++) { // 遍历每个桶
            for (int j = 0; j < bucket[i]; j++) { // 遍历桶里面的元素
                result[k++] = i;
            }
        }

        return result;
    }

    /**
     * @Description 获取分数数组
     * @Param []
     * @return int[]
     **/
    private static int[] getScoreArr() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入数组长度:");
        int n = scanner.nextInt();

        int[] scoreArr = new int[n];
        for (int i = 0; i < n; i++) {
            System.out.printf("请输入第%d个数(范围:0-10),然后按回车: ", i+1);
            scoreArr[i] = scanner.nextInt();
        }

        return scoreArr;
    }
}

演示

运行代码,控制台输入可得:
在这里插入图片描述

升级版

正如作者所说,上文演示的只是一个简易版的桶排序算法。

那如果需要输入多个学生的姓名和分数,再根据学生的分数排名由高到低输出学生的姓名,这样要怎么做呢?

作者这里并没有给出答案,我们来扩展一下,首先创建一个学生类:

package com.guqueyue.aHaAlgorithm.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author: guqueyue
 * @Description: 学生类
 * @Date: 2024/1/9
 **/
//lombok插件的注解
@Data // 若未使用lombok插件,请自行生成getter、setter以及toString方法
@NoArgsConstructor // 若未使用lombok插件,请自行生成无参构造方法
@AllArgsConstructor // 若未使用lombok插件,请自行生成有参构造方法
public class Student {

    private String name; // 姓名
    private Integer score; // 分数
}

核心代码

同理,我们使用桶排序,得到一个通过分数降序排序的学生数组:

	/**
     * @Description 桶排序 - 通过分数排序学生数组
     * @Param [scoreArr]
     * @return com.guqueyue.aHaAlgorithm.entity.Student[]
     **/
    private static Student[] bucketSort(Student[] scoreArr) {

        Student[] result = new Student[scoreArr.length];
        // 桶排序,将分数入桶
        int[] bucket = new int[101];
        for (Student student : scoreArr) {
            bucket[student.getScore()]++;
        }

        int k = 0;
        for (int i = 100; i >= 0; i--) { // 倒序遍历桶
            if (bucket[i] > 0) {
                for (Student student : scoreArr) { // 遍历学生数组,将符合当前桶的分数的学生放入数组
                    if (student.getScore() == i) {
                        result[k++] = student;
                    }
                }
            }
        }

        return result;
    }

完整代码

package com.guqueyue.aHaAlgorithm.chapter_1_Sort;

import com.guqueyue.aHaAlgorithm.entity.Student;

import java.util.*;

/**
 * @Author: guqueyue
 * @Description: 桶排序 - 通过分数排序学生数组
 * @Date: 2024/1/9
 **/
public class BucketSort2 {
    public static void main(String[] args) {

        Student[] scoreArr = getStudentArr(); // 获取学生数组
        System.out.println("输入的数组为:" + Arrays.toString(scoreArr));

        Student[] result = bucketSort(scoreArr);
        System.out.println("排序后的数组为: " + Arrays.toString(result));

        System.out.print("学生排名为: ");
        for (Student student : result) {
            System.out.print(student.getName() + " ");
        }
        System.out.println();
    }

    /**
     * @Description 桶排序 - 通过分数排序学生数组
     * @Param [scoreArr]
     * @return com.guqueyue.aHaAlgorithm.entity.Student[]
     **/
    private static Student[] bucketSort(Student[] scoreArr) {

        Student[] result = new Student[scoreArr.length];
        // 桶排序,将分数入桶
        int[] bucket = new int[101];
        for (Student student : scoreArr) {
            bucket[student.getScore()]++;
        }

        int k = 0;
        for (int i = 100; i >= 0; i--) { // 倒序遍历桶
            if (bucket[i] > 0) {
                for (Student student : scoreArr) { // 遍历学生数组,将符合当前桶的分数的学生放入数组
                    if (student.getScore() == i) {
                        result[k++] = student;
                    }
                }
            }
        }

        return result;
    }

    /**
     * @Description 桶排序优化版 - 通过分数排序学生数组
     * @Param [scoreArr]
     * @return com.guqueyue.aHaAlgorithm.entity.Student[]
     **/
    private static Student[] bucketSort2(Student[] scoreArr) {

        // 1.构建 分数 -> 人名集合 映射集
        Map<Integer, List<Student>> dict = new HashMap<>();
        for (Student student : scoreArr) {

            Integer score = student.getScore();
            List<Student> studentList = new ArrayList<>();
            if (dict.containsKey(score)) {
                studentList = dict.get(score);
            }

            studentList.add(student);
            dict.put(score, studentList);
        }

        Student[] result = new Student[scoreArr.length];
        // 桶排序
        int[] bucket = new int[101];
        for (Student student : scoreArr) {
            bucket[student.getScore()]++;
        }

        int k = 0;
        for (int i = 100; i >= 0; i--) {
            if (bucket[i] > 0) { // 如果有
                List<Student> students = dict.get(i);
                if (students != null && students.size() > 0) {
                    for (Student student : students) {
                        result[k++] = student;
                    }
                }
            }
        }

        return result;
    }

    /**
     * @Description 获取学生数组
     * @Param []
     * @return com.guqueyue.aHaAlgorithm.entity.Student[]
     **/
    private static Student[] getStudentArr() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入学生数量:");
        int n = scanner.nextInt();
        Student[] students = new Student[n];

        for (int i = 0; i < n; i++) {
            Student student = new Student();

            System.out.printf("请输入第%d个学生的姓名:", i+1);
            student.setName(scanner.next());
            System.out.printf("请输入第%d个学生的分数(0-100):", i+1);
            student.setScore(scanner.nextInt());

            students[i] = student;
        }

        return students;
    }
}

演示

运行代码,控制台输入,可得:
在这里插入图片描述

我们下期博客再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/346950.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s的安全机制

k8s是分布式集群管理工具&#xff0c;k8s作用是容器编排 1、安全机制核心&#xff1a;API server。API server作为整个集群内部通信的中介&#xff0c;也是外部控制的入口&#xff0c;所有的安全机制都是围绕api sserver来进行设计的。请求api server资源要满足3个条件&#x…

Garbage First收集器(简称G1)

概述&#xff1a;Garbage First&#xff08;简称G1&#xff09;收集器是垃圾收集器技术发展历史上的里程碑式的成果&#xff0c;它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。 G1开创的基于Region的堆内存布局是它能够实现这个目标的关键。虽然G1也仍是遵…

开始学习Vue(路由)

一、什么是路由 SPA 指的是一个 web 网站只有唯一的一个 HTML 页面&#xff0c;所有组 件的展示与切换都在这唯一的一个页面内完成。 此时&#xff0c;不同组件之间的切换需要通过前端路由来实现。 结论&#xff1a;在 SPA 项目中&#xff0c;不同功能之间的切换&#xff0…

无人机航迹规划(六):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…

LP-AM243x EtherNet/IP 连接施耐德 M241 EIP主站测试

硬件环境&#xff1a;LP-AM243x 开发板 施耐德 Modicon M241 软件环境&#xff1a; INDUSTRIAL-COMMUNICATIONS-SDK-AM243X MCU-PLUS-SDK-AM243X — MCU SDK for AM243x 调试过程&#xff1a; 首先&#xff0c;让AM243x能够运行 Null Boot&#xff0c; Starting NULL Boo…

力扣hot100 除自身以外数组的乘积 前后缀积

Problem: 238. 除自身以外数组的乘积 文章目录 思路前后缀积 思路 前后缀积 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) class Solution {public int[] productExceptSelf(int[] nums){int n nums.length;int[] p new int[n];//除…

Obsidian - 使用小记(Typora切换过来)

文章目录 关于 Obsidian打开已有的 文件夹将图片改为 Typora 的保存文件夹 关于 Obsidian 官网 https://obsidian.md/github : https://github.com/obsidianmd 个人版免费 一直习惯用 Typora 编写markdown git 记录笔记&#xff0c;多次被安利 Obsidian 后&#xff0c;今天尝…

解决TortoiseGit软件Git Show log时显示Too many files to display的问题

1 问题描述 有时代码提交修改的文件比较多&#xff0c;当查看log时无法显示出来修改的文件列表&#xff0c;如下所示&#xff1a; 2 解决方法 将LogTooManyItemsThreshold尽可能配置得大一些。 三 参考资料 https://gitlab.com/tortoisegit/tortoisegit/-/issues/3878

session反序列化

据陈腾师傅所说&#xff1a; 1.漏洞产生原因&#xff1a;写入格式和读取格式不一样。 下面是三种常见的存储格式&#xff1a; 处理器 对应的存储格式 php键名竖线经过serialize()函数序列化处理的值php_serialize(php>5.54)经…

vue3+Element plus实现登录功能

一、想要实现的效果 二、搭建登录静态 1、实现左边背景和右边登录栏的总体布局布局&#xff1a; <el-row class"content"><!--el-col 列&#xff1a; --><el-col :span"16" :xs"0" class"content-left"></el-c…

司铭宇老师:电话销售心态培训:电话销售被拒绝怎么调整心态

电话销售心态培训&#xff1a;电话销售被拒绝怎么调整心态 在电话销售这个行业中&#xff0c;遭遇拒绝是家常便饭。无论你如何努力&#xff0c;总有那么些时候&#xff0c;客户会对你的产品或服务说“不”。然而&#xff0c;这并不意味着你的努力白费。关键在于如何调整心态&am…

洗内裤的小洗衣机买啥牌子的?四款家用小洗衣机推荐

随着内衣洗衣机的流行&#xff0c;很多小伙伴在纠结该不该入手一款内衣洗衣机&#xff0c;专门来洗一些贴身衣物&#xff0c;答案是非常有必要的&#xff0c;因为我们现在市面上的大型洗衣机只能做清洁&#xff0c;无法对我们的贴身衣物进行一个高强度的清洁&#xff0c;而小小…

Java|IDEA 运行和打包报错解决

IDEA 运行和打包报错解决 java.lang.NoSuchFieldError&#xff1a;com.sun.tools.javac.tree.JCTree$JCImport 报错信息 环境&#xff1a;JDK 21 java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field com.sun.t…

Messari发布重磅研报,波场TRON 2023 Q4期间实现多项突破

近日,顶级加密数据研究机构Messari发布了波场TRON 2023 Q4调研报告,报告从网络数据、生态、稳定币和RWA等多个方面对波场TRON进行了细致研究,并给与了波场TRON极大的肯定。这份调研报告帮助投资者和社区更好地了解波场TRON的发展前景和竞争优势。同时,这些数据和见解可以提高投…

嵌入式学习五

使用circuit JS模拟器讲解 一&#xff1a;欧姆定律 演示电压电阻的关系 欧姆定律 二&#xff1a;电阻 计算电阻串并联的阻值 电阻 电阻越串越大&#xff0c;越并越小 并联电路增加通路 三&#xff1a;电容器 观察电容的充放电 电容器 电容就是一个临时存储电量的容器 当电…

Unity_使用Image和脚本生成虚线段

生成如图样式的虚线段 原理&#xff1a;使用Image做一条线段&#xff0c;这个方法的原理就是给固定的片元长度&#xff0c;对Image进行分割&#xff0c;把片元添加到一个列表中&#xff0c;然后循环对列表中的偶数位进行隐藏&#xff0c;也可以调整线段的宽度 缺陷&#xff1…

力扣hot100 LRU 缓存 有序Map

Problem: 146. LRU 缓存 文章目录 思路&#x1f496; Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 &#x1f469;‍&#x1f3eb; 参考图解 &#x1f496; Code ⏰ 两操作 时间复杂度: O ( 1 ) O(1) O(1) class LRUCache {int cap;LinkedHashMap<Integer, In…

【并发】什么是 AQS

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 AQS的主要特征和方法包括&#xff1a; 状态管理&#xff1a; 等待队列&#xff1a; 独占模式&#xff1a; 共享模式&#xff1…

提高塑料制品的塑料透光率测量仪

塑料透光率检测仪是一种用于测量塑料材料透光率的仪器。透光率是指光线通过材料后&#xff0c;被吸收、反射和散射的量与总光线量的比例。塑料透光率检测仪在塑料制品的研发、生产和质量控制等方面具有广泛的应用。 塑料透光率检测仪的原理是使用光束通过待测塑料样品&#xff…

PageHelper学习使用

基于mybatis源码和PageHelper源码进行的测试 版本 mybatis3.5.0&#xff0c;pageHelper6.0.0 测试用例 依赖 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.15</version> &…
最新文章