归并排序

归并排序

归并排序和基于交换,选择等排序的思想不一样,“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表含有n个记录,则可以看成是n个有序的子表,每个子表长度为1,然后两两归并,得到⌈n/2⌉个长度为2或1的有序表:再两两归并,……如此重复,直到合成一个长度为n的有序表为止,这种排序方法称为2-路归并排序。下图是一个归并排序的例子:

image

子表合并

设两段有序表A[low…mid],A[mid+1…high]存放在同一顺序表中相邻的位置上,每次从这两个表中取出最小的元素放到临时数组中去,直到两个表中的元素被全部取完。这样临时数组中存储着A[low…high]的所有元素且有序,然后将临时数组的元素copy回原素组A[low…high],这样就完成了子表合并的问题。

public static void merge(int[] arr, int low, int mid, int high){
        int[] tmp = new int[high-low+1]; //分配一个临时数组
        int k,i,j;
        for(i=low,j=mid+1,k=0; i<=mid&&j<=high; k++){
            if(arr[i]<=arr[j])      //比较arr中的左右两子表的元素
                tmp[k] = arr[i++]; //将较小值复制到临时数组中
            else
                tmp[k] = arr[j++];
        } 
        //将有剩余元素的那个子表复制到tmp中
        while(i<=mid) tmp[k++] = arr[i++];
        while(j<=high) tmp[k++] = arr[j++];
        //tmp数组的元素已有序,将其复制回原数组对应的位置
        System.arraycopy(tmp, 0, arr, low, tmp.length); 
    }

排序代码

public static void mergeSort(int[] arr, int low, int high){
        if(low < high){
            int mid = (low + high)/2;
            mergeSort(arr, low, mid);
            mergeSort(arr, mid+1, high);
            merge(arr, low, mid, high);
        }
    }
posted @ 2016-11-15 22:23  被罚站的树  阅读(338)  评论(5编辑  收藏  举报