归并排序mergesort中基本的操作是合并两个已排序的表。因为这两个表已排序,所以若将输出放到第三个表中,则该算法可以通过对输入数据一趟排序完成。基本的合并算法是取两个输入数组A和B,一个输出数组C,以及3个计数器Actr、Bctr、Cctr,他们初始置于对应数组的开始端。A[Actr]和B[Bctr]中的较小者被拷贝到C的下一个位置,相关的计数器向前推进一步。当两个输入表有一个用完的时候,则将另一个表中剩余部分拷贝到C中。
合并另个已排序的表的时间显然是线性的,因为最多进行N-1次比较,其中N是元素的总数。每次比较都把一个元素添加到C中,除了最后的比较。
归并排序很容易描述,如果N=1,那么只有一个元素需要排序,否则递归地将前半部分数据和后半部分数据各自归并排序,得到排序后的两部分数据,然后使用合并算法再将这两部分合并到一起。与其它的O(NlogN)排序算法比较,归并算法的运行时间严重依赖于比较元素和在数组及临时数组中移动元素的相对开销。这些开销是与语言相关的。
以下为归并排序算法的实现代码:
import java.util.Random;
public class SortAlgorithm {
/**
* 归并排序
* @param array 数组
*/
public static > void mergeSort(
AnyType[] array) {
count=0;
@SuppressWarnings("unchecked")
AnyType[] tmpArray = (AnyType[]) new Comparable[array.length];
mergeSort(array, tmpArray, 0, array.length - 1);
}
/**
* 归并排序递归调用的内部方法
* @param array 需要排序的数组
* @param tmpArray 存放归并结果的数组
* @param left 子数组的最左下标
* @param right 子数组的最右下标
*/
private static > void mergeSort(
AnyType[] array, AnyType[] tmpArray, int left, int right) {
if (left < right) {
int center = (left + right) / 2;
mergeSort(array, tmpArray, left, center);
mergeSort(array, tmpArray, center + 1, right);
merge(array, tmpArray, left, center + 1, right);
}
}
/**
* 将两个子数组归并的算法
* @param array 需要排序的数组
* @param tmpArray 存放归并结果的数组
* @param leftPos 子数组的最左下标
* @param rightPos 子数组后半部分的开始下标
* @param rightEnd 子数组最右下标
*/
private static > void merge(
AnyType[] array, AnyType[] tmpArray, int leftPos, int rightPos,
int rightEnd) {
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
// 主循环
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (array[leftPos].compareTo(array[rightPos]) <= 0) {
tmpArray[tmpPos++] = array[leftPos++];
} else {
tmpArray[tmpPos++] = array[rightPos++];
}
}
while (leftPos <= leftEnd) {
tmpArray[tmpPos++] = array[leftPos++];
}
while (rightPos <= rightEnd) {
tmpArray[tmpPos++] = array[rightPos++];
}
//复制tmpArray中内容到array
for (int i = 0; i < numElements; i++) {
array[rightEnd] = tmpArray[rightEnd];
rightEnd--;
}
}
public static void main(String[] args) {
Integer[] list1 = new Integer[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
for (int i = 0; i < 10; i++) {
System.out.print(list1[i] + " ");
}
System.out.println();
mergeSort(list1);
System.out.println("After sorting:");
for (Integer integer : list1) {
System.out.print(integer + " ");
}
System.out.println("\n---------------------");
Integer[] list2 = new Integer[20];
Random random = new Random();
for (int i = 0; i < 20; i++) {
list2[i] = random.nextInt(20);
System.out.print(list2[i] + " ");
}
System.out.println();
mergeSort(list2);
System.out.println("After sorting:");
for (Integer integer : list2) {
System.out.print(integer + " ");
}
}
}
执行结果:
9 8 7 6 5 4 3 2 1 0
After sorting:
0 1 2 3 4 5 6 7 8 9
---------------------
0 6 18 7 18 7 2 0 6 10 9 16 19 10 15 8 3 19 10 18
After sorting:
0 0 2 3 6 6 7 7 8 9 10 10 10 15 16 18 18 18 19 19
版权声明:本文为博主原创文章,未经博主允许不得转载。