归并排序(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数组要作为传参
    当然大佬们可以按照自身需求尝试修改代码实现,这里展示其中一种代码实现思路。
归并排序 (Mergesort) 是一种分治算法,它将待排序数组分成两半,分别对每一半进行排序,然后合并两个已排序的部分。在 C 语言中,实现归并排序主要包括 `mergesort` 函数和辅助的 `merge` 函数。 `mergesort` 函数通常包含以下步骤: 1. **划分**:如果数组长度大于1,则将其一分为二。 2. **递归**:对左右两个子数组分别进行递归调用 `mergesort`。 3. **合并**:当所有元素都被排序后,通过 `merge` 函数将这两个有序数组合并成一个整体。 `merge` 函数负责合并两个已经排好序的子数组,它的工作原理是: 1. 创建一个新的临时数组用于存放合并后的结果。 2. 分别从两个输入数组的起始位置开始比较元素,选择较小的放入临时数组,并更新对应原数组的位置。 3. 重复上述过程直到有一个数组的所有元素都已经被添加到临时数组。 4. 将另一个数组剩余部分直接复制到临时数组的未填充部分。 以下是简单的 C 代码示例: ```c #include <stdio.h> #include <stdlib.h> // merge function to combine two sorted arrays into one void merge(int arr[], int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m; // create temporary arrays int L[n1], R[n2]; // copy elements from the first array to temp for (i = 0; i < n1; i++) L[i] = arr[l + i]; // copy elements from the second array to temp for (j = 0; j < n2; j++) R[j] = arr[m + 1+ j]; // merge the temp arrays back into arr[l..r] i = 0; j = 0; k = l; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } // copy remaining elements of L[] if any while (i < n1) { arr[k] = L[i]; i++; k++; } // copy remaining elements of R[] if any while (j < n2) { arr[k] = R[j]; j++; k++; } } // mergesort function void mergesort(int arr[], int l, int r) { if (l < r) { int m = l+(r-l)/2; mergesort(arr, l, m); mergesort(arr, m+1, r); merge(arr, l, m, r); } } int main() { int arr[] = {12, 11, 13, 5, 6, 7}; int arr_size = sizeof(arr) / sizeof(arr[0]); mergesort(arr, 0, arr_size - 1); printf("Sorted array: \n"); for (int i = 0; i < arr_size; i++) printf("%d ", arr[i]); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值