Java函数实现归并排序算法的原理及代码示例
发布时间:2023-06-06 22:35:22
归并排序(Merge Sort)是一种基于分治思想的排序算法,它将一个待排序的序列不断分割成两个子序列,直到每个子序列都只有一个元素为止,然后将这些子序列归并(Merge)。归并操作是将两个已经排好序的子序列合并成一个有序的序列。
归并排序算法的复杂度为O(nlogn),比较适合处理大规模数据的排序问题。下面我们来详细介绍一下归并排序算法的实现原理和代码示例。
1. 归并排序的实现原理
归并排序的实现原理可以简述为以下几步:
- 将待排序的序列分成两个子序列,分别对两个子序列进行递归排序,直到子序列只有一个元素为止;
- 将排好序的子序列合并为一个有序序列。
实现这两个步骤需要使用到归并操作,归并操作的实现可以分为以下几步:
- 创建一个临时数组;
- 从两个有序的子序列中取出 个元素,比较大小,将较小的元素放入临时数组中,并从所属子序列中取出下一个元素继续比较;
- 重复步骤2,直到一个子序列中的所有元素都被放入临时数组中,然后将剩余的子序列中的元素依次放入临时数组中;
- 将临时数组中的元素复制回原来的数组中。
2. 归并排序的代码示例
接下来是归并排序的Java实现代码。
public class MergeSort {
/*
* 归并排序
* 参数说明:
* a -- 待排序的数组
*/
public static void mergeSort(int[] a) {
int[] tmp = new int[a.length];
sort(a, 0, a.length - 1, tmp);
}
private static void sort(int[] a, int left, int right, int[] tmp) {
if (left < right) {
int mid = (left + right) / 2;
sort(a, left, mid, tmp); // 左边归并排序,使得左子序列有序
sort(a, mid + 1, right, tmp); // 右边归并排序,使得右子序列有序
merge(a, left, mid, right, tmp); // 将两个有序子数组合并操作
}
}
private static void merge(int[] a, int left, int mid, int right, int[] tmp) {
int i = left; // 左序列指针
int j = mid + 1; // 右序列指针
int t = 0; // 临时数组指针
while (i <= mid && j <= right) {
if (a[i] <= a[j]) {
tmp[t++] = a[i++];
} else {
tmp[t++] = a[j++];
}
}
while (i <= mid) { // 将左边剩余元素填充进tmp中
tmp[t++] = a[i++];
}
while (j <= right) { // 将右序列剩余元素填充进tmp中
tmp[t++] = a[j++];
}
t = 0;
// 将tmp中的元素全部拷贝回a中
while (left <= right) {
a[left++] = tmp[t++];
}
}
public static void main(String[] args) {
int[] arr = { 49, 38, 65, 97, 76, 13, 27, 49 };
MergeSort.mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
}
这段代码涉及到了归并排序的所有操作,主要是merge()函数实现的归并操作,将两个有序子数组合并为一个有序的数组。
这里用到了一个临时数组tmp,表示合并操作中所需要的内存空间。在归并排序的过程中,每次递归调用sort()函数时都需要创建一个新的临时数组,随着递归的深入,创建的临时数组的大小也会逐渐增加,最大不会超过待排序数组的长度,因此归并排序的空间复杂度为O(n)。
总的来说,归并排序算法的实现比较简单,但是要注意细节问题,例如边界条件和临时数组的使用等。
