首先先讲一下归并排序的基本操作方法
给定一个数组,
data[] {4, 9, 52, 11, 8, 67, 23, 3, 2, 32};
1.我们将该数组分为两部分
左数组为[4, 9, 52, 11, 8]
右数组为[67, 23, 3, 2, 32]
2.将左右数组的头和尾的下标分别记为left1,right1,left2,right2
如:刚开始具体为left1== 0,right1 == 4,left2 == 5,right2 == 9
3.先将左数组进行排序,再将右数组进行排序,最后进行归并
4.在将左,右数组进行排序时进行递归重复进行2,3步直到前面2个数组有序,然后将两个数组进行归并
5.具体代码如下
public class MergeSortTest {
public static void mergeSort(int[] data) {
sort(data, 0, data.length - 1);
}
/**
* 进行递归
* @param data 数组
* @param left1 左边数组第一个数的下标,也是数组第一个数的下标
* @param right2 右边数组最后一个数的下标,也是数组最后一个数的下标
*/
public static void sort(int[] data, int left1, int right2) {
if (left1 >= right2)
return;
// 找出中间索引
int right1 = (left1 + right2) / 2;
// 对左边数组进行递归
sort(data, left1, right1);
// 对右边数组进行递归
sort(data, right1 + 1, right2);
// 合并
merge(data, left1, right1, right2);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data 数组对象
* @param left1 左数组的第一个元素的索引
* @param right1 左数组的最后一个元素的索引,right1+1是右数组第一个元素的索引
* @param right2 右数组最后一个元素的索引
*/
public static void merge(int[] data, int left1, int right1, int right2) {
// 临时数组
int[] brr = new int[data.length];
int left2 = right1 + 1; // 右数组第一个元素索引
int j = left1;// 记录临时数组的索引
int tmp = left1; // 记录左数组第一个元素的索引
while (left1 <= right1 && left2 <= right2) {
// 从两个数组中取出最小的放入临时数组
if (data[left1] <= data[left2]) {
brr[j++] = data[left1++];
} else {
brr[j++] = data[left2++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (left2 <= right2) {
brr[j++] = data[left2++];
}
while (left1 <= right1) {
brr[j++] = data[left1++];
}
// 将临时数组中的内容拷贝回原数组中
// (原来被改变顺序的范围的内容被复制回原数组)
while (tmp <= right2) {
data[tmp] = brr[tmp++];
}
}
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}
public static void main(String[] args) {
int[] data = new int[] { 4, 9, 52, 11, 8, 67, 23, 3, 2, 32 };
print(data);
mergeSort(data);
System.out.println("排序后的数组:");
print(data);
}
}