归并排序 --- 进入现在的公司被面的算法

本文详细介绍了归并排序的基本原理,并通过一个具体的Java实现案例,深入浅出地讲解了如何进行递归拆分及合并操作。同时,还特别指出了在合并过程中需要注意的三个关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 原理

可参考https://www.cnblogs.com/chengxiao/p/6194356.html

2小记

下面的算法是我按照自己的理解写的,调了1个多小时,请着重注意一下merge上的注释,以及我标的3个注意点

3 代码

package com.nrsc.sort;

public class MergeSort {
	public static void main(String[] args) {
		int[] arr = { 49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
		mergeSort(arr, 0, arr.length - 1);
		System.out.println("排序后:");
		for (int i : arr) {
			System.out.println(i);
		}
	}

	/**
	 * 归并排序
	 * 
	 * @param arr
	 * @param left
	 * @param right
	 */
	private static void mergeSort(int[] arr, int left, int right) {
		if (left < right) {

			// 取中间值
			int middle = (left + right) / 2;
			// 对中间值左边进行排序----不断拆分
			mergeSort(arr, left, middle);
			// 对中间值右边进行排序----不断拆分
			mergeSort(arr, middle + 1, right);
			// 将左右两个排好序的数组进行合并
			merge(arr, left, middle, right);
		}

	}

	/**
	 * 左右两个排好序的数组进行合并 这两个数组在原arr中下标分别为
	 * arr[left~,middle]和arr[middle+1,right]
	 * 这里必须要非常明确(只有这里明确了,才能知道为什么会有注意点1和3)
	 * 
	 * @param arr    原始数组
	 * @param left
	 * @param middle
	 * @param right
	 */
	private static void merge(int[] arr, int left, int middle, int right) {

		// 新建一个临时数组用来存放排好序的数
		int[] tmp = new int[arr.length];
		
		//注意点1
		int ls = left;// 左边数组的第一个下标
		int ts = left;// 临时数组tmp的最左边的下标
		int rs = middle + 1; // 右边数组的第一个下标

		// 当两个数组都没到末尾时,谁小,将谁先放进临时数组tmp
		while (ls <= middle && rs <= right) {
			if (arr[ls] < arr[rs]) {
				tmp[ts++] = arr[ls++];
			} else {
				tmp[ts++] = arr[rs++];
			}
		}
		//注意点2
		// 能走到这里有两种情况,或者ls>middle了,或者rs>right了,
		// 也就是左边或右边至少有一个数组已经全部放到新数组tmp里了

		// 如果这时候ls<=middle,则此时ls~middle的值比已经放进tmp的数都大,只需将其依次放入tmp就好了
		while (ls <= middle) {
			tmp[ts++] = arr[ls++];
		}

		// 同理,如果此时rs<=righe,说明此时rs~right的值比已经放进tmp的数都大,只需将其依次放入tmp就好了
		while (rs <= right) {
			tmp[ts++] = arr[rs++];
		}
		//注意点3
		// 将tmp数组赋值给arr------tmp是有序数组
		while (left <= right) {
			arr[left] = tmp[left++];
		}

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nrsc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值