归并排序(Merge Sort)是一种分而治之的算法,它将原始数组分成越来越小的子数组,直到每个子数组只有一个元素,然后将这些子数组两两合并,过程中保持排序状态,最终合并成一个完全有序的数组。归并排序是一种稳定的排序算法,其主要特点是效率高且易于理解。
归并排序的基本步骤:
- 分解:将当前区间一分为二,即求中点。
- 递归排序:递归地对两个子区间a[low...mid]和a[mid+1...high]进行归并排序。
- 合并:将已排序的两个子区间合并成一个有序区间。
时间复杂度和空间复杂度:
-
时间复杂度:归并排序的时间复杂度为O(n log n),无论是最好、最坏还是平均情况都是如此,因为它总是将数组分成两半进行处理,然后合并,这个过程与数组的初始状态无关。
-
空间复杂度:由于归并排序需要一个与原数组相同大小的临时数组来合并子数组,所以其空间复杂度为O(n)。
稳定性**:
归并排序是稳定的排序算法,因为在合并两个子数组时,如果遇到相等的元素,会先将左侧子数组的元素加入结果数组,保持原有顺序不变。
以下是归并排序的实现示例图:
以下是实现归并排序的Java代码:
public class MergeSort {
// 合并两个子数组
private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
// 将排序后的元素复制回原数组
System.arraycopy(temp, 0, arr, left, right - left + 1);
}
// 主函数,递归进行归并排序
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp); // 排序左半部分
mergeSort(arr, mid + 1, right, temp); // 排序右半部分
merge(arr, left, mid, right, temp); // 合并两个有序部分
}
}
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6, 7};
int[] temp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, temp);
System.out.println("Sorted array: ");
for (int num : arr) {
System.out.print(num + " ");
}
}
}