您的位置:首页 > 编程语言 > Java开发

归并排序(Merge Sort)递归、非递归 Java实现

2017-05-08 13:33 363 查看
归并排序与堆排序充分利用了完全二叉树的深度为logn + 1的特性,因而效率比较高。

归并排序(Merge Sort)
归并排序(Merge Sort)就是利用归并的思想表现的排序方法。
它的原理是假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止这种排序方法称为2路归并排序。
import java.util.Arrays;
import java.util.Random;

/**
* 归并排序
*
*/
public class MergeSort {

public void mergeSort(int[] arr) {
// 递归
sort(arr, 0, arr.length - 1);

System.out.println(Arrays.toString(arr));

// 非递归
sort(arr);

System.out.println(Arrays.toString(arr));
}

/**
* 归并排序(递归实现)
* 时间复杂度 O(nlogn)
* 空间复杂度O(n + logn)
* @param arr
* @param left
* @param right
*/
private void sort(int[] arr, int left, int right) {
if (left >= right)
return;

int mid = (left + right) / 2;
// 左边
sort(arr, left, mid);
// 右边
sort(arr, mid + 1, right);
// 合并并排序
merge(arr, left, mid, right);
}

/**
* 归并排序(非递归实现)
* 时间复杂度O(nlogn)
* 空间复杂度O(n)
* @param arr
*/
private void sort(int[] arr) {
// 从 1开始分割,与递归不同的是,递归由数组长度一分为二最后到1,
// 而非递归则是从1开始扩大二倍直到数组长度
int len = 1;

while (arr.length > len) {

// 完全二叉树一层内的遍历
for (int i = 0; i + len <= arr.length - 1; i += len * 2) {
int left = i;
int mid = i + len - 1;
int right = i + len * 2 - 1;

// 防止超出数组长度
if (right > arr.length - 1)
right = arr.length - 1;

// 合并排序相同
merge(arr, left, mid, right);
}

// 下一层
len *= 2;
}
}

/**
* 合并并排序
* @param arr
* @param left
* @param mid
* @param right
*/
private void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];

int i = left;
int j = mid + 1;
int k = 0;

// 注意: 此处并没有全部放入temp中,当一边达到mid或right时就是退出循环
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++];

// 排好序的临时数组重新放入原数组
for (int m = 0; m < temp.length; m++) {
arr[m + left] = temp[m];
}
}

public static void main(String[] args) {
//		int[] arr = {9, 1, 5, 8, 3, 7, 4, 6, 2};

int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = new Random().nextInt(50);
}

System.out.println(Arrays.toString(arr));

new MergeSort().mergeSort(arr);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息