Java玩转《啊哈算法》排序综合篇之小哼买书

是诸法空相,不生不灭,不垢不净,不增不减

非目录

  • 缘起
  • 代码地址
  • 案例
    • 桶排序
    • 冒泡排序
    • 快速排序

缘起

各位大哥大姐,兄弟姐妹们好呀!本人最近看了下《啊哈算法》,说来惭愧,买几年了,当初看了一会儿就吃灰了。

不过写的确实蛮好的,生动形象,精准有趣。

但稍显遗憾的是,书籍示例代码是c语言,不是本人常用的Java。

那就弥补遗憾,说干就干,把这本书的示例语言用java走一遍!!! 顺便附上自己的一些理解。

于是就有了本篇博客,本篇主要是通过一个具体案例,总结一下之前讲的三个排序算法:

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

  2. Java玩转《啊哈算法》排序之冒泡排序

  3. 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即可!

案例

按照本书,给出了一个案例:

小哼的学校要建立一个图书角,老师派小哼去找一些同学做调查,看看同学们都喜欢读哪些书。小哼让每个同学写出一个自己最想读的书的ISBN号(你知道吗?每本书都有唯一的ISBN号,不信的话你去找本书翻到背面看看)。当然有一些好书会有很多同学都喜欢,这样就会收集到很多重复的ISBN号。小哼需要去掉其中重复的ISBN号,即每个ISBN号只保留一个,也就说同样的书只买一本(学校真是够抠门的)。然后再把这些ISBN号从小到大排序,小哼将按照排序好的ISBN号去书店买书。请你协助小哼完成 “去重” 与 “排序” 的工作。

在这里插入图片描述

当然,我们这里为了方便,做一下输入限制:

输入有2行,
第1行为一个正整数,表示有n个同学参与调查(n≤100)。
第2行有n 个用空格隔开的正整数,为每本图书的ISBN号(假设图书的ISBN号在1~1000之间)。

然后我们需要输出:

输出也是 2 行,
第 1 行为一个正整数 k,表示需要买多少本书。
第 2 行为 k 个用空格隔开的正整数,为从小到大已排好序的需要购买的图书的 ISBN 号。

根据题目,我们不难得出,题目分为 去重排序计数 三步。那么这道题用三种排序算法要怎么做呢?

我们来分析一下:

  1. 如果是用桶排序的话,我们直接入桶的同时并计数,然后输出有元素的桶就好。
  2. 如果使用冒泡排序或者快速排序的话,需要先升序排序,然后再判断是否有重复的元素并计数。

话不多说,下面直接上代码,具体解释看代码注释就好了。

桶排序

核心代码:

 	/*** @Description 桶排序 - 去重* @Param [arr: 待去重排序后的数组]* @return**/private static void bucketSort(int[] arr) {int count = 0; // 声明变量,用于计数int[] bucket = new int[1001];for (int i : arr) { // 遍历数组if(bucket[i] == 0) { // 计数count++;}bucket[i]++; // 入桶}System.out.println("需要买书的本数为: " + count);System.out.print("得到去重排序后的ISBN号数组为: ");for (int i = 0; i < 1001; i++) { // 遍历桶if (bucket[i] > 0) { // 桶内有数,则输出桶System.out.print(i + " ");}}// 换行System.out.println();}

完整代码:

package com.guqueyue.aHaAlgorithm.chapter_1_Sort;import java.util.Scanner;/*** @Author: guqueyue* @Description: 小哼买书,去书籍的ISBN号进行去重排序* @Date: 2024/1/10**/
public class BuyBook {public static void main(String[] args) {// 获取书籍的ISBN号int[] arr = getArr();// 桶排序bucketSort(arr);}/*** @Description 桶排序 - 去重* @Param [arr: 待去重排序后的数组]* @return**/private static void bucketSort(int[] arr) {int count = 0; // 声明变量,用于计数int[] bucket = new int[1001];for (int i : arr) { // 遍历数组if(bucket[i] == 0) { // 计数count++;}bucket[i]++; // 入桶}System.out.println("需要买书的本数为: " + count);System.out.print("得到去重排序后的ISBN号数组为: ");for (int i = 0; i < 1001; i++) { // 遍历桶if (bucket[i] > 0) { // 桶内有数,则输出桶System.out.print(i + " ");}}// 换行System.out.println();}/*** @Description 获取书籍的ISBN号* @Param []* @return int[]**/private static int[] getArr() {Scanner scanner = new Scanner(System.in);System.out.print("请输入书籍数: ");int n = scanner.nextInt();int[] arr = new int[n];System.out.printf("请输入第%d本书的ISBN号(0-1000), 中间用空格隔开,再回车:", n);for (int i = 0; i < n; i++) {arr[i] = scanner.nextInt();}return arr;}
}

演示:
在这里插入图片描述

大功告成!

冒泡排序

冒泡排序跟桶排序不同的是,它是先排序,再进行去重和计数

而其中排序的代码跟之前的博客的内容别无二致,但是需要增加去重和计数的代码:

 		// 去重计数int count = 1;String str = arr[0] + " "; // 保存第一个数for (int i = 1; i < arr.length; i++) {if (arr[i] != arr[i-1]) { // 与前一个不相等则存起来方便输出str += arr[i] + " ";count++; // 计数}}// 输出System.out.println("需要买书的本数为: " + count);System.out.println("得到去重排序后的ISBN号数组为: " + str);

完整代码:

package com.guqueyue.aHaAlgorithm.chapter_1_Sort;import java.util.Arrays;
import java.util.Scanner;/*** @Author: guqueyue* @Description: 小哼买书,去书籍的ISBN号进行去重排序 - 冒泡排序* @Date: 2024/1/10**/
public class BuyBook2 {public static void main(String[] args) {// 获取书籍的ISBN号int[] arr = getArr();// 冒泡排序bubbleSort(arr);System.out.println("得到排序后的ISBN号数组为: " + Arrays.toString(arr));// 去重计数int count = 1;String str = arr[0] + " "; // 保存第一个数for (int i = 1; i < arr.length; i++) {if (arr[i] != arr[i-1]) { // 与前一个不相等则存起来方便输出str += arr[i] + " ";count++; // 计数}}// 输出System.out.println("需要买书的本数为: " + count);System.out.println("得到去重排序后的ISBN号数组为: " + str);}/*** @Description 冒泡排序 * @Param [arr]* @return int[]**/private static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) { // 交换for (int j = 1; j < n-i; j++) {if (arr[j] < arr[j-1]) {int t = arr[j]; arr[j] = arr[j-1]; arr[j-1] = t;}}}}/*** @Description 获取书籍的ISBN号* @Param []* @return int[]**/private static int[] getArr() {Scanner scanner = new Scanner(System.in);System.out.print("请输入书籍数: ");int n = scanner.nextInt();int[] arr = new int[n];System.out.printf("请输入第%d本书的ISBN号(0-1000), 中间用空格隔开,再回车:", n);for (int i = 0; i < n; i++) {arr[i] = scanner.nextInt();}return arr;}
}

运行代码,控制台输入,可得:

在这里插入图片描述

快速排序

快速排序跟冒泡排序类似,都是先排序,再进行去重和计数,无非是排序的算法发生了变化:

package com.guqueyue.aHaAlgorithm.chapter_1_Sort;import java.util.Arrays;
import java.util.Scanner;/*** @Author: guqueyue* @Description: 小哼买书,去书籍的ISBN号进行去重排序 - 快速排序* @Date: 2024/1/10**/
public class BuyBook3 {public static void main(String[] args) {// 获取书籍的ISBN号int[] arr = getArr();// 快速排序quickSort(arr, 0, arr.length-1);System.out.println("得到排序后的ISBN号数组为: " + Arrays.toString(arr));// 去重计数int count = 1;String str = arr[0] + " "; // 保存第一个数for (int i = 1; i < arr.length; i++) {if (arr[i] != arr[i-1]) { // 与前一个不相等则存起来方便输出str += arr[i] + " ";count++; // 计数}}// 输出System.out.println("需要买书的本数为: " + count);System.out.println("得到去重排序后的ISBN号数组为: " + str);}/*** @Description 快速排序* @Param [arr, left, right]* @return void**/private static void quickSort(int[] arr, int left, int right) {if (left >= right) {return;}int i = left, j = right, temp = arr[left]; // temp为基准值while (i < j) { // 相遇了就不能继续找了// 右边的先找while (arr[j] >= temp && i < j) {j--;}// 左边的后找while (arr[i] <= temp && i < j) {i++;}// 如果没有相遇,则交换if (i < j) {int t = arr[i];arr[i] = arr[j];arr[j] = t;}}// 交换基准值arr[left] = arr[i];arr[i] = temp;// 继续左边找quickSort(arr, left, i-1);// 继续右边找quickSort(arr, i+1, right);}/*** @Description 获取书籍的ISBN号* @Param []* @return int[]**/private static int[] getArr() {Scanner scanner = new Scanner(System.in);System.out.print("请输入书籍数: ");int n = scanner.nextInt();int[] arr = new int[n];System.out.printf("请输入第%d本书的ISBN号(0-1000), 中间用空格隔开,再回车:", n);for (int i = 0; i < n; i++) {arr[i] = scanner.nextInt();}return arr;}
}

启动程序,输入可得:

在这里插入图片描述
完美!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Office提取某一页转成图片

目录结构 前言支持的文件格式代码整理maven依赖文本文档解析转换电子表格解析转换演示文档解析转换PDF解析转换小编代码整理(完整版)特别感谢扩展前言 近期公司需求,要将office文件提取第一页内容转成图片;一番调查后整理如下: 支持的文件格式 文本文档电子表格演示文档…

协会认证!百望云荣获信创工委会年度“卓越贡献成员单位”称号

当前&#xff0c;新一轮科技革命和产业变革正加速重塑全球经济结构&#xff0c;强化企业科技创新的主体地位&#xff0c;推动创新链、产业链、人才链深度融合&#xff0c;加快科技成果产业化进程至关重要。 近日&#xff0c;中国电子工业标准化技术协会信息技术应用创新工作委员…

HTTP中传输协议的数据格式

HTTP 概述&#xff1a;超文本传输协议(Hyper Text Transfer Protocol) 传输协议&#xff1a;定义了客户端和服务器通信时&#xff0c;发送数据的格式 客户端和服务器端交互&#xff1a;客户端向服务器端发送请求&#xff0c;服务器端向客户端响应请求 HTTP特点&#xff1a;…

安装mysql和navicat

1 安装mysql 以下是 MySQL 的安装教程: 步骤 1:下载 MySQL 首先在官方网站上下载 MySQL 安装包。在下载页面中选择第一个安装包,然后点击“下载”按钮,下载后解压缩。 下载地址 步骤 2:配置环境变量 配置MYSQL_HOME path 中添加%MYSQL_HOME%\bin 添加 my.ini ,内容…

1月威胁态势 | 0day占比83%!两大勒索家族“均分天下”

近日&#xff0c;亚信安全正式发布《亚信安全2024年1月威胁态势报告》&#xff08;以下简称“报告”&#xff09;报告显示&#xff0c;1月份新增安全漏洞1511个&#xff0c;涉及0day漏洞占83%&#xff1b;监测发现当前较活跃的勒索病毒家族是Wacatac和Nemucod&#xff0c;病毒样…

【C++】vector的简单使用和实现

vector就是我们之前数据结构学的顺序表&#xff0c;这篇博客就是说一说它的简单使用和底层实现 文章目录 简单使用模拟实现 简单使用 首先&#xff0c;我们看看它的构造函数 我们比较常用的也就是第二种&#xff0c;就是第一个参数是要存的数据个数&#xff0c;第二个是要填…

Python实现利用仅有像素级标注的json文件生成框标注的json文件,并存放到新文件夹

import json import os # create rectangle labels based on polygon labels, and store in a new folder def create_rectangle_shapes(polygon_shapes):rectangle_shapes []for polygon_shape in polygon_shapes:# 获取多边形的坐标点points polygon_shape[points]# 找到最…

node 第二十四天 mongoDB shell 命令 高级方法 $where aggregate聚合

$where 数据库数据如下 使用where语法如下 等价于 2.aggregate 聚合 使用聚合管道执行聚合操作。该管道允许用户通过一系列基于阶段的操作来处理来自集合或其他源的数据。 过滤数据, 分组数据 (排除name为 AAA 的数据 按price进行分组 每匹配一组计数1) 下面我们用aggregate…

新一轮范式转移的焦点:边缘

在万物互联的时代里 数据的洪流 正在慢慢转向边缘 &#x1f447;&#x1f447;&#x1f447; 当成千上万的设备接入互联网&#xff0c;大量数据正在边缘产生。在新一轮范式转移的过程中&#xff0c;边缘成为创建和处理数据的关键枢纽。企业该如何有效地管理边缘数据&#x…

Qt QWidget Loading界面并覆盖在其他控件上面

目录 一、效果图二、Loading三、使用 一、效果图 界面中有一个Label&#xff0c;一个Button 点击Buttion&#xff0c;显示Loading的界面&#xff0c;并覆盖到Label和Button上面 二、Loading loadingwidget.h #ifndef LOADINGWIDGET_H #define LOADINGWIDGET_H#include <…

Linux 网络配置及基础服务

目录 一. 查看网络配置信息的相关命令 1.1 ifconfig 命令 作用 1&#xff1a; 作用 2&#xff1a; 拓展&#xff1a; 1.2 ip/ethtool命令 1.3 hostname命令 1.4 route 命令 1.5 netstat 命令 1.6 ss&#xff08;socket statistics&#xff09;命令 1.7 ping 命令 …

小白级教程,10秒开服《幻兽帕鲁》

在帕鲁的世界&#xff0c;你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活&#xff0c;也可以为你在工厂工作。你也可以将它们进行售卖&#xff0c;或肢解后食用。 前言 马上过年…

STM32——感应开关盖垃圾桶

STM32——感应开关盖垃圾桶 1.定时器介绍 软件定时 缺点&#xff1a;不精确、占用CPU资源 void Delay500ms() //11.0592MHz {unsigned char i, j, k;_nop_();i 4;j 129;k 119;do{do{while (--k);} while (--j);} while (--i); }定时器工作原理 使用精准的时基&#xff…

算法面试八股文『 基础知识篇 』

博客介绍 近期在准备算法面试&#xff0c;网上信息杂乱不规整&#xff0c;出于强迫症就自己整理了算法面试常出现的考题。独乐乐不如众乐乐&#xff0c;与其奖励自己&#xff0c;不如大家一起嗨。以下整理的内容可能有不足之处&#xff0c;欢迎大佬一起讨论。 PS&#xff1a;…

Redis常见问题

击穿 概念&#xff1a;在Redis获取某一key时, 由于key不存在, 而必须向DB发起一次请求的行为, 称为“Redis击穿”。 引发击穿的原因&#xff1a; 第一次访问恶意访问不存在的keyKey过期 合理的规避方案&#xff1a; 服务器启动时, 提前写入规范key的命名, 通过中间件拦截对…

Kotlin:用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系‘

Kotlin&#xff1a;用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系’ 在这篇文章中&#xff0c;我们将深入研究Kotlin中的StateFlow和SharedFlow&#xff0c;以及它们的相似之处和不同之处。我们将通过查看它们的源代码来理解它们的工作原理&#xff0c;这将帮助我们更…

【五】【C++】类与对象(三)

const只读 在 C 中&#xff0c;const 关键字用于声明一个变量为常量&#xff0c;意味着一旦被初始化之后&#xff0c;它的值就不能被改变。 声明常量&#xff1a; 使用 const 关键字可以声明变量为常量。这意味着这个变量的值不能被修改。 const int MAX_SIZE 100; 指针与…

Quartus生成烧录到FPGA板载Flash的jic文件

简要说明&#xff1a; Altera的FPGA芯片有两种基本分类&#xff0c;一类是纯FPGA&#xff0c;另一类是FPGASoc&#xff08;System on chip)&#xff0c;也就是FPGAHPS&#xff08;Hard Processor System&#xff0c;硬核处理器&#xff09;&#xff0c;对应两种Flash烧录方式&a…

【HTML】自定义属性(data)

自定义属性 data: 的用法&#xff08;如何设置,如何获取) &#xff0c;有何优势&#xff1f; data-* 的值的获取和设置&#xff0c;2种方法: 传统方法 getAttribute() 获取 data- 属性值; setAttribute() 设置 data- 属性值getAttribute() 获取 data- 属性值; setAttribute()…

什么是自动化测试分层?3个层次从高到低又是哪些?

自动化测试分层&#xff0c;可以理解为将测试任务分解为多个层次&#xff0c;并在每个层次中定义特定的测试任务和测试范围&#xff0c;通过这种方式&#xff0c;测试人员可以更好地管理和组织测试工作&#xff0c;确保测试的全面性和准确性。 自动化测试可以分解为3个层次&am…