</pre><pre name="code" class="java">归并排序时算法是将两个或两个以上的有序表合并成一个新的有序表,即把待排序的序列分成若干个有序的子序列,再把有序的子序列合并成为整体有序序列。
该算法是采用分治法的一个典型的应用
百度百科的解释:<a target=_blank href="http://baike.baidu.com/view/90797.htm?fr=aladdin" target="_blank">点击打开链接http://baike.baidu.com/view/90797.htm?fr=aladdin</a>
(做事情,首先要搞清楚定义,所以最先找的应该是wiki。。。这里就懒了,列的是百度百科的哈)
package com.sortdemo;
/*
* 很多算法在结构上递归的,为了解决一个给定的问题,算法要一次或多次的递归调用其自身来
* 解决相关的问题。这些算法通常采用分治策略:将原问题划分成n个规模较小的而结构与原问题
* 相似的子问题,然后在合并其结果,得到原问题的解。
* 分治模式在每一层递归上都有三个步骤:
* 分解(Divide) :将原问题分解为一系列子问题
* 解决(Conquer):递归的解各子问题,若子问题足够小,则直接求解。
* 合并(Combine):将子问题的结果合并成原问题的解
* */
public class MergeSort {
public static void merge(int []A, int p, int q, int r){
// p <= q < r A[p,q] A[q+1,r]排序好了
int n1 = q - p + 1; //A[p,q]长度
int n2 = r - q; //A[q+1,r]长度
int []L = new int[n1 + 1]; //多出的一个作为哨兵,避免检查每个堆是空堆
int []R = new int[n2 + 1]; //左堆和右堆两个数组
for(int i = 1; i <= n1; i++){ //初始化堆 刚开始的时候有问题这里,
//可以想象下,在数次递归后,最初传来的值是A[0]、A[1],此时p,q为0,r为1,不注意的话这里容易引起数组过界的问题
L[i-1] = A[p + i -1];
}
for(int j = 1; j <= n2; j++){ //初始化堆
R[j-1] = A[q + j];
}
L[n1] = 100000; //哨兵置于末尾,大于A中所有元素的值
R[n2] = 100000;
int m = 0;
int n =0;
for(int k = p; k <= r; k++){ //执行 r-p+1步骤
if(L[m] <= R[n]){
A[k] = L[m];
m++;
}
else{
A[k] = R[n];
n++;
}
}
}
//对子数组A[p,q]进行排序
public static void mergesort(int []A, int p,int r){
if(p < r)
{
int q = (p + r)/2;
mergesort(A,p,q);
mergesort(A,q+1,r);
merge(A,p,q,r);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] A = {15,11,13,18,16,12,31,22,19};
System.out.println("初始数组:");
for(int i = 0; i<A.length; i++)
{
System.out.print(A[i]+" ");
}
mergesort(A,0,A.length-1);
System.out.println("排序后数组:");
for(int i = 0; i<A.length; i++)
{
System.out.print(A[i]+" ");
}
}
}