基本思想:将待排序序列R[0…n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。
实现代码
public class MergeSort
{
public static void main(String[] args)
{
DataWrap[] dataWraps =
{ new DataWrap(9, ""), new DataWrap(-16, ""), new DataWrap(21, "*"),
new DataWrap(23, ""), new DataWrap(-30, "*"),
new DataWrap(-49, "*"), new DataWrap(21, ""),
new DataWrap(30, "*"), new DataWrap(13, "*"),
new DataWrap(15, ""), new DataWrap(28, "*"),
new DataWrap(-2, "*") };
System.out.println("排序之前:\n" + Arrays.toString(dataWraps));
mergeSort(dataWraps);
System.out.println("排序之后:\n" + Arrays.toString(dataWraps));
}
public static void mergeSort(DataWrap[] dataWraps)
{
sort(dataWraps, 0, dataWraps.length - 1);
}
private static void sort(DataWrap[] dataWraps, int left, int right)
{
if (left < right)
{
// 中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
sort(dataWraps, left, center);
// 对右边数组进行递归
sort(dataWraps, center + 1, right);
System.out.println("left:" + left + " right:" + right);
// 归并
merge(dataWraps, left, center, right);
}
}
private static void merge(DataWrap[] dataWraps, int left, int center,
int right)
{
DataWrap[] arrTmp = new DataWrap[dataWraps.length];
int mid = center + 1;
int third = left;
int tmp = left;
while (left <= center && mid <= right)
{
// 将两个数组中取小放入临时数组
if (dataWraps[left].compareTo(dataWraps[mid]) < 0)
{
arrTmp[third++] = dataWraps[left++];
} else
{
arrTmp[third++] = dataWraps[mid++];
}
}
// 原数组剩余部分放入临时数组
while (mid <= right)
{
arrTmp[third++] = dataWraps[mid++];
}
while (left <= center)
{
arrTmp[third++] = dataWraps[left++];
}
// 临时数组内容拷贝到原数组
while (tmp <= right)
{
dataWraps[tmp] = arrTmp[tmp++];
}
System.out.println(Arrays.toString(dataWraps));
}
}
时间复杂度:O(n/log2n)