用java语言归并排序_排序算法(Java语言)——归并排序

归并排序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

版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值