归并排序(mergeSort)代码实现

归并排序通过递归思路实现,类似二叉树的后序遍历,先分别排序左右子数组,再合并。核心是双指针合并排序数组。注意排序过程中数组元素索引变化,代码实现中直接修改原数组。

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

归并排序整体的代码实现与二叉树的后序遍历有异曲同工之处,即先遍历左子树(i.e. 排序[left, mid]数组元素),后遍历右子树(i.e. 排序[mid + 1, right]数组元素),最后遍历根节点(i.e.合并排序后的左、右子树)。

代码实现中涉及到的常用编程思路:
  • 递归: 归并排序sort(array, left, right)代码实现的整体思路
    涉及到树的遍历,一般与递归算法或栈相关
public void mergeSort(int[] array) {
	sort(array, 0, array.length - 1);
}

public void sort(int[] array, int left, int right) {
	if (left < right) {
		int mid = left + (right - left) / 2;
		sort(array, left, mid); // 将[left, mid]的元素排序
		sort(array, mid + 1, right); // 将[mid + 1, right]的元素排序
		merge(array, left, mid, right); // 合并并排序两个排序好的数组
	}
}
  • 双指针:合并两个数组merge(array, left, mid, right)的主要思路
    合并两个排序数组通常会联想到用双指针分别索引两个数组的元素(leetcode有类似的题目)
public void merge(int[] array, int left, int mid, int right) {
	int[] arr = new int[right - left + 1]; // 储存合并后的数组
	int p = 0, p1 = left, p2 = mid + 1; // p: arr; p1: array[left : mid]; p2: array[mid + 1 : right]
	 1. 两两比较放入arr中
	while (p1 <= mid && p2 <= right) { // arr[p] = array[p1] > array[p2] ? array[p2] : [p1]
		if (array[p1] > array[p2]) {
			arr[p] = array[p2];
			p2++;
		} else {
			arr[p] = array[p1];
			p1++;
		}
		p++;
			/* 等价:
			if (array[p1] > array[p2]) {
				arr[p++] = array[p2++];
			} else {
				arr[p++] = array[p1++];
			}
			*/
	}
	
	 2. 将剩余没有进行两两比较的元素(如果有的话)依次放入arr中
	while (p1 <= mid) { // 如果[left, mid]还有元素未放入arr中
		arr[p] = array[p1];
		p1++; 
		p++;
			// 等价:arr[p++] = array[p1++];
	}
	while (p2 <= right) {// 如果[mid + 1, right]还有元素未放入arr中
		arr[p] = array[p2];
		p2++; 
		p++;
			// 等价:arr[p++] = array[p2++];
	}
	
	 3. arr放入array[left, right]
	for (int i = left; i <= right; i++) {
		array[i] = arr[i - left];
	}
}
注意事项

因为函数直接对数组进行修改,而不是新生成一个数组,所以与此有关要注意的方面:

  • 排序后数组元素的索引发生改变
    在遇到需要返回元素索引而不是元素本身的问题时需要注意,可以考虑将索引构造一个数组,在元素排序的同时索引数组也相应的改变。
  • 返回类型void数组要作为传参
    当然大佬们可以按照自身需求尝试修改代码实现,这里展示其中一种代码实现思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值