AcWing算法基础课-787归并排序-Java题解

news2024/9/22 11:38:14

heweilai-bolg-title-image-of-the-article

大家好,我是何未来,本篇文章给大家讲解《AcWing算法基础课》787 题——归并排序。本文详细介绍了归并排序的算法思路,包括分解、合并和递归排序三个主要步骤。通过 Java 代码实现,展示了如何将数组递归分解至单个元素,再逐步合并成有序数组。

文章目录

  • ❓题目描述
  • 💡算法思路
  • ✅Java代码
  • 🔗参考

❓题目描述

给定你一个长度为 n 的整数数列。

请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整个数列。

输出格式

输出共一行,包含 n 个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

💡算法思路

  1. 分解:将数组从中间分成两个子数组,直到每个子数组只包含一个元素。这一步通过递归实现,确保每个子数组都是有序的(单个元素自然是有序的)。
  2. 合并:将两个有序的子数组合并成一个有序的数组。这一步是归并排序的关键。合并过程中,程序会比较两个子数组中的元素,按顺序将较小的元素放入临时数组中,直到所有元素都被合并。
  3. 递归排序:在递归的每一层,程序都会对分解后的子数组进行排序,然后合并结果。最终,整个数组会被排序。

具体实现步骤:

  1. 基本检查:首先,检查传入的数组部分是否只有一个元素或为空。如果是,则不需要进一步排序,直接返回。
  2. 计算中间位置:计算当前数组部分的中间位置,这个中间位置将用于将数组分成两部分。
  3. 递归排序左半部分:对数组的左半部分(从左边界到中间位置)进行递归排序。
  4. 递归排序右半部分:对数组的右半部分(从中间位置的下一个位置到右边界)进行递归排序。
  5. 初始化合并变量:初始化三个变量:k用于跟踪临时数组的索引,i用于遍历左半部分的数组,j用于遍历右半部分的数组。
  6. 合并两个有序数组:比较左半部分和右半部分的元素,将较小的元素放入临时数组tmp中,直到其中一个部分的元素全部放入临时数组。
  7. 处理左半部分剩余元素:如果左半部分还有剩余元素,将它们全部放入临时数组。
  8. 处理右半部分剩余元素:如果右半部分还有剩余元素,将它们全部放入临时数组。
  9. 将临时数组复制回原数组:将临时数组tmp中的元素复制回原数组a的相应位置,完成合并排序。

时间复杂度:O(n log n)
空间复杂度:O(n)
稳定排序:在合并过程中,相等元素的次序保持不变。

✅Java代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class Aw787 {

	// 创建一个StreamTokenizer用于读取输入
	static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

	// 读取下一个整数的方法
	static int nextInt() throws IOException {
		in.nextToken();
		return (int) in.nval;
	}

	static int n; // 存储数组的大小
	static int[] nums = new int[100000 + 10]; // 存储输入的数组,预留一些额外的空间
	static int[] tmp = new int[100000 + 10]; // 临时数组,用于合并排序

	public static void main(String[] args) throws IOException {
		n = nextInt(); // 读取数组的大小
		for (int i = 0; i < n; i++) {
			nums[i] = nextInt(); // 读取数组的每个元素
		}
		mergeSort(0, n - 1, nums); // 调用归并排序方法对数组进行排序
		for (int i = 0; i < n; i++) {
			System.out.print(nums[i] + " "); // 输出排序后的数组
		}
	}

	// 归并排序方法,参数为数组的起始和结束索引,以及数组本身
	static void mergeSort(int l, int r, int[] a) {
		if (l >= r) { // 如果起始索引大于或等于结束索引,则直接返回
			return;
		}
		int mid = l + r >> 1; // 计算中间索引
		mergeSort(l, mid, a); // 递归排序左半部分
		mergeSort(mid + 1, r, a); // 递归排序右半部分
		// i表示左子数组的起始位置,j表示右子数组的起始位置
		// k表示tmp的结束位置
		int k = 0, i = l, j = mid + 1; // 初始化指针k, i, j
		while (i <= mid && j <= r) { // 合并两个有序子数组
			if (a[i] <= a[j]) { // 如果左半部分的元素小于或等于右半部分的元素
				tmp[k++] = a[i++]; // 将左半部分的元素放入临时数组
			} else {
				tmp[k++] = a[j++]; // 否则将右半部分的元素放入临时数组
			}
		}
		while (i <= mid) { // 如果左半部分还有剩余元素
			tmp[k++] = a[i++]; // 将剩余元素放入临时数组
		}
		while (j <= r) { // 如果右半部分还有剩余元素
			tmp[k++] = a[j++]; // 将剩余元素放入临时数组
		}
		for (i = l, j = 0; i <= r; i++, j++) { // 将临时数组中的元素复制回原数组
			a[i] = tmp[j];
		}
	}

}

🔗参考

  • https://www.acwing.com/problem/content/789/
  • https://www.hello-algo.com/chapter_sorting/merge_sort/

作者:程序员何未来-heweilai.com


🔍推荐阅读

  1. AcWing算法基础课-786第k个数-Java题解
  2. AcWing算法基础课-785快速排序-Java题解
  3. 【七夕节实践】把爱心代码放在自己的网站上是什么体验?

欢迎关注我的博客:@程序员何未来,持续为你输出有价值的技术文章~
你们的点赞👍 收藏⭐ 留言🗨️ 关注✅
是我持续创作,输出优质内容的最大动力!谢谢!

文章关键词:算法,计算机算法,算法题解,算法竞赛,Java,数据结构,AcWing算法基础课

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

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

相关文章

揭秘!焦虑症与气血不足:是巧合还是内在关联?

在这个快节奏、高压力的时代&#xff0c;焦虑症仿佛成了现代人难以言说的“隐形伴侣”。失眠、心悸、易怒……这些症状让许多人苦不堪言。而另一边&#xff0c;中医理论中的“气血不足”也常常被视为身体虚弱、情绪不稳的根源。那么&#xff0c;焦虑症与气血不足之间&#xff0…

EMLOG程序单页友链和标签增加美化

单页友联效果图&#xff1a; 标签页面效果图&#xff1a; 源码介绍 EMLOG单页友情链接和TAG标签&#xff0c;友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样&#xff0c;如果自适应就填写100%&#xff0c;TAG文件不用修改 安装方法&#xff1a…

使用Selenium与WebDriver实现跨浏览器自动化数据抓取

背景/引言 在数据驱动的时代&#xff0c;网络爬虫成为了收集和分析海量数据的关键工具。为了应对不同浏览器环境下的兼容性问题&#xff0c;Selenium与WebDriver成为了开发者实现跨浏览器自动化数据抓取的首选工具。本文将深入探讨如何利用Selenium和WebDriver实现跨浏览器的数…

客户管理太难了?你可能忽视了这些常见问题

在客户管理中&#xff0c;你是不是常常感到力不从心&#xff1f;客户信息不准确、沟通不到位、客户流失毫无预警……这些问题不仅让管理者头疼&#xff0c;还严重影响企业的业绩增长。客户管理看似简单&#xff0c;但往往隐藏着很多不易察觉的细节问题。如果你觉得客户越来越难…

什么运动耳机好用?六大技巧助力选购优质产品

​开放式蓝牙耳机现在超流行&#xff0c;不仅年轻人爱用&#xff0c;连不少上了年纪的人也喜欢在公园里散步时戴上。这些耳机无论是听歌、学习、健身还是办公&#xff0c;都能派上用场。到了2024年&#xff0c;想要挑到一款既好用又好听的开放式蓝牙耳机&#xff0c;得好好比较…

Vue2+JS项目升级为Vue3+TS之jquery的maphilight引入项目

本人由于想提升自己的项目开发能力&#xff0c;所以将就项目的vue2JavaScriptwebpack的旧技术栈升级为vue3typescriptvite的技术栈&#xff0c;所以遇到很多坑&#xff0c;以下是maphilight的解决方法。 众所周知jquery是基于JavaScript进行开发&#xff0c;但是已有typescript…

LiveKit的agent介绍

概念 LiveKit核心概念&#xff1a; Room&#xff08;房间&#xff09;Participant&#xff08;参会人&#xff09;Track&#xff08;信息流追踪&#xff09; Agent 架构图 ​ 订阅信息流 ​ agent交互流程 客户端操作 加入房间 房间创建方式 手动 赋予用户创建房间的…

【原创】java+springboot+mysql校园疫情管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【JAVA开源】基于Vue和SpringBoot的图书个性化推荐系统

本文项目编号 T 015 &#xff0c;文末自助获取源码 \color{red}{T015&#xff0c;文末自助获取源码} T015&#xff0c;文末自助获取源码 目录 一、系统介绍1.1 业务分析1.2 用例设计1.3 时序设计 二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究…

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习&#xff1a;参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归&#xff08;SAheart.csv&#xff09; 【学习笔记】 陈强-机器学习-Python-…

[AHK] 调用函数动态生成ListBox窗口

需求背景 动态生成向导对话框&#xff0c;由用户选一个选项&#xff0c;类似做选择题。 运行效果 AHK v1 代码 if(A_ScriptFullPathA_LineFile)MsgBox % ListBox("窗口标题", "这是一个生成listbox的Demo", "a|b|c|d|",3) return ;---------…

【小沐学OpenGL】Ubuntu环境下glew的安装和使用

文章目录 1、简介1.1 OpenGL简介1.2 glew简介 2、安装glew2.1 命令安装glew2.2 直接代码安装glew2.3 cmake代码安装glew 3、测试glew3.1 测试glewfreeglut3.2 测试glewglfw 结语 1、简介 1.1 OpenGL简介 Linux 系统中的 OpenGL 是一个跨语言、跨平台的应用程序编程接口&#…

智能的PHP开发工具PhpStorm v2024.2全新发布——支持日志文件

PhpStorm是一个轻量级且便捷的PHP IDE&#xff0c;其旨在提高用户效率&#xff0c;可深刻理解用户的编码&#xff0c;提供智能代码补全&#xff0c;快速导航以及即时错误检查。可随时帮助用户对其编码进行调整&#xff0c;运行单元测试或者提供可视化debug功能。 立即获取PhpS…

【私活儿分享】手串珠子管理小程序,便捷查询珠子(串手链的珠子)位置

前言 之间帮客户做了个查询手串珠子位置的小程序&#xff0c;便于帮助客户管理众多的珠子&#xff0c;这个珠子就是戴在手上串起来的饰品。好了&#xff0c;话不多说&#xff0c;进入正题&#xff01; 正文 小程序比较简单&#xff0c;采用云开发。两个页面&#xff0c;一个查…

Git 新手指南

Git 命令大全 Git 是目前最流行的分布式版本控制系统&#xff0c;用于跟踪文件的更改&#xff0c;协调不同开发者的协作。掌握 Git 命令能够极大提高工作效率&#xff0c;尤其在软件开发过程中。本文将详细介绍 Git 的一些常用命令&#xff0c;帮助你更好地理解和使用 Git。 1…

一款免费开源的截图软件,SETUNA截图软件

SETUNA是一款功能强大且便捷的屏幕截图工具&#xff0c;适用于多种场景&#xff0c;包括日常办公、学习和游戏娱乐等。该软件的主要特点如下&#xff1a; 高效截图&#xff1a;用户可以轻松截取屏幕上的任何部分&#xff0c;并且支持自定义选取截图范围。图片编辑功能&#xf…

聊聊go语言channel中的一些小技巧

写在文章开头 go语言提供了各种非常方便的语法糖&#xff0c;使得我们实现用最少的语法做尽可能高效的事情&#xff0c;而本文就简单介绍如何实现非阻塞处理多个channel&#xff0c;希望对你有帮助。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的技…

项目进度一

一.双token验证登陆/注册 1.在前端中&#xff0c;得到响应记录acessToken和 refreshToken ,并记录在 localStorage中&#xff0c;当登录之后的请求都要携带着accessToken,如果accessToken过期&#xff0c;就再验证一下refreshToken&#xff0c;如果也过期就需要重新登录&#…

亚马逊测评自养号卖家如何以低成本提高店铺产品曝光率和销量?

在跨境电商领域&#xff0c;随着市场日趋饱和和竞争加剧&#xff0c;卖家普遍面临流量低、转化率低的共同挑战。为了在这种严重的“内卷化”环境中脱颖而出&#xff0c;不少卖家投入了大量的资金和资源&#xff0c;尝试了各种站内和站外的推广方式&#xff0c;但往往因为缺乏成…

Vue2中使用ant-design的tab组件让他一行充满

使用tabs组件默认样式这样 想改成水平居中铺满如下&#xff1a; 需要改下css样式 /deep/ .ant-tabs-nav {width: 100%;& > div {width: 100%;display: flex;align-items: center;}.ant-tabs-tab {flex: 1;text-align: center;}}