归并:将两个或两个以上的有序表组合成一个新的有序表。
一般情况不用这种方式排序,只有在将多个有序序列整合成一个有序序列是才会用到归并排序,才能想归并效率体现的最高。
算法描叙:
1、设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1。
2、两两合并,得到 n/2 个长度为2或1的有序子序列。
3、再两两合并,……如此重复,直至得到一个长度为n的有序序列为止。
个人见解:也就是先将一个无序的序列对半拆分,将拆分后的序列继续拆分,直到拆分成一个元素为一个序列为止,然后在将两个这样的子序列有序的合并成一个序列,以此往回合并,从而达到排序的效果。(思想很容易理解,就是实现起来有点麻烦)
例:
public class SortMethods {
/*输出数组中的元素*/
private static void print(int[] a) {
for(int num: a){
System.out.print(num+"\t");
}
System.out.println();
}
private static void swap(int[] a, int i, int j) {
int temp;
temp =a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int a[] = {0,21,25,49,25,16,15,8,-2,0,-9,67,34,5,12,40};
shellSort(a);
print(a);
}
private static void mergeSort(int[] a, int left, int right) {
if(left<right){//至少有2个元素
int mid = (left+right)/2; //二分,取中点
//把序列拆分成两个子序列:[left,mid] 和 [mid+1,right]
//同时还要对分解后的子序列分别进行递归“归并排序”
mergeSort(a,left,mid);
mergeSort(a,mid+1,right);
//把前面两个已经排好序的子序列进行归并
int b[] = new int[a.length];
merge(a,b,left,mid,right);
copyArray(a,b,left,right);
}
}
private static void copyArray(int[] a, int[] b, int left, int right) {//这里也可以直接用system中的copyArray来代替
for(int i=left;i<=right;i++){
a[i] = b[i];
}
}
//把两个已经排好序的子序列(a[left,mid]和a[mid+1,right]) 合并成一个 ( b[left,right] )
private static void merge(int[] a, int[] b, int left, int mid, int right) {
int p = left;
int r=mid+1;
int k=left;
while( p<=mid && r<=right ){
if(a[p]<=a[r]){
b[k++] = a[p++];
}else{
b[k++] = a[r++];
}
}
//此时,肯定有一个子序列中的元素全部移到b[]数组,因此,只要把还未移完的子序列当中的所有剩余元素直接对拷到数组b[]当中即可
if(p>mid){//左子序列已经完成。因此剩下的是右序列,对拷右序列当中的剩余元素即可
for(int i=r;i<=right;i++){
b[k++]=a[i];
}
}else{//对拷左子序列中的剩余元素
for(int i=p;i<=mid;i++){
b[k++]=a[i];
}
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/u011479875/article/details/47188907