归并排序的核心思想是将一个大的数组分割成多个小的子数组,然后分别对这些子数组进行排序,最后将排序后的子数组合并起来,得到一个有序的大数组。
归并排序(Merge Sort)是一种经典的排序算法,其原理基于分治(Divide and Conquer)策略。它的核心思想是将一个大问题分割成多个小问题,解决小问题后再将它们合并以得到最终结果。
public static void mergeSort(int[] array) {
if (array == null || array.length <= 1) {
return; // 如果数组为空或只有一个元素,无需排序
}
int[] temp = new int[array.length]; // 创建一个临时数组来辅助排序
mergeSort(array, 0, array.length - 1, temp); // 调用归并排序函数
}
private static void mergeSort(int[] array, int left, int right, int[] temp) {
//直到每个子数组只包含一个元素 即:left == right
//也就是说最小排序单位是长度为2的数组,当长度为2时,此时无法再递归,而进行排序
if (left < right) {
int mid = (left + right) / 2;
// 对左半部分进行归并排序
mergeSort(array, left, mid, temp);
// 对右半部分进行归并排序
mergeSort(array, mid + 1, right, temp);
// 合并两个有序数组
merge(array, left, mid, right, temp);
}
}
private static void merge(int[] array, int left, int mid, int right, int[] temp) {
int i = left; // 左数组的起始索引
int j = mid + 1; // 右数组的起始索引
int k = left; // 临时数组的起始索引
// 比较左右两个数组的元素,将较小的元素放入临时数组
while (i <= mid && j <= right) {
if (array[i] <= array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
// 将左数组剩余部分复制到临时数组
while (i <= mid) {
temp[k++] = array[i++];
}
// 将右数组剩余部分复制到临时数组
while (j <= right) {
temp[k++] = array[j++];
}
// 将临时数组的元素复制回原数组
for (i = left; i <= right; i++) {
array[i] = temp[i];
}
}
时间复杂度(最坏) | 时间复杂度(最好) | 时间复杂度(平均) | 空间复杂度 | 稳定性 |
---|---|---|---|---|
O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
上述代码实现了基本的归并排序算法,但它在合并过程中存在一个潜在的优化点。在归并排序的合并阶段,将左右两个有序数组合并为一个有序数组时,可以通过判断左边数组的最大值和右边数组的最小值来优化合并操作,避免不必要的比较。
这个优化点可以通过添加一个条件来判断是否需要合并,如果左边数组的最大值小于等于右边数组的最小值,则无需合并,因为两个数组已经是有序的,不需要进行额外的比较和移动。
private static void merge(int[] array, int left, int mid, int right, int[] temp) {
int i = left; // 左数组的起始索引
int j = mid + 1; // 右数组的起始索引
int k = left; // 临时数组的起始索引
// 如果左数组的最大值小于等于右数组的最小值,则无需合并,直接返回
if (array[mid] <= array[j]) {
return;
}
// 比较左右两个数组的元素,将较小的元素放入临时数组
while (i <= mid && j <= right) {
if (array[i] <= array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
// 将左数组剩余部分复制到临时数组
while (i <= mid) {
temp[k++] = array[i++];
}
// 将右数组剩余部分复制到临时数组
while (j <= right) {
temp[k++] = array[j++];
}
// 将临时数组的元素复制回原数组
for (i = left; i <= right; i++) {
array[i] = temp[i];
}
}
这个优化逻辑在判断左右两个子数组已经有序时,可以避免不必要的比较和赋值操作,提升归并排序的性能。
归并排序核心就是 递归,分治,记住这两个词就能大致理解这个算法,递归思想真的很重要,不容易完全理解,还得继续练习-_-
相关概念
• 稳定
:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
• 不稳定
:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
• 时间复杂度
:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
• 空间复杂度
:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。
原文地址:https://blog.csdn.net/WriteBug001/article/details/134812841
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_49002.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!