Java-归并排序

1.原理/思路

 归并排序的设计思路是:将待排序的数组分为两个字数组,分别对它们按同样的方式进行排序,最后将两个有序子数组
 归并成一个有序数组。

2.分析做法

1.将当前序列一分为二,求出分裂点mid = (left + right) / 2;
2.对子序列arr[left,mid]递归,进行归并排序,结果放入data[left,mid]中;
3.对子序列arr[mid+1,right]递归,进行归并排序,结果放入data[mid+1,right]中;
4.调用算法merge,将有序的两个子序列归并成一个有序的序列data[left,right]。

3.代码实现

public int[] mergeSort(int[] arr){

    sort(arr,0,arr.length - 1);
    return arr;
}

public void sort(int[] arr,int left,int right){

    if(left >= right)
    return;

    //将当前序列一分为二,求出分裂点mid
    int mid = (left + right) / 2;
    //二路归并排序里面有两个Sort,多路归并排序里面写多个Sort就可以了
    sort(arr,left,mid);
    sort(arr,mid+1,right);
    //左右归并
    merge(arr,left,mid,right);
}

private void merge(int[] arr,int left,int mid,int right){

    int[] temps = new int[right - left + 1];
    //左指针
    int i = left;
    //右指针
    int j = mid + 1;
    int k = 0;
    // 把较小的数先移到新数组中
    while (i <= mid && j <= right){
        if(arr[i] < arr[j]){
            temps[k++] = arr[i++];
        }else{
            temps[k++] = arr[j++];
        }
    }
    // 把左边剩余的数移入数组
    while (i <= mid){
        temps[k++] = arr[i++];
    }
    // 把右边边剩余的数移入数组
    while (j <= right){
        temps[k++] = arr[j++];
    }
    System.out.println("第"+(++number)+"趟排序:\t");
    //从临时数组拷贝到原数组
    for (int l = 0; l < temps.length; l++) {
        arr[left + l] = temps[l];
        //输出中间归并排序结果
        System.out.print(arr[left + l]+"\t");
    }
    System.out.println();
}

4.测试

@Test
public void test(){
    int arr[] = {0,1,1,2,3,3,4,8,7,6,12,22,65};
    //int arr[] = {6,3,8,2,9,1};
    System.out.println("排序前");
    printArr(arr);
    int[] data = mergeSort(arr);
    System.out.println("排序后");
    printArr(data);
}

public void printArr(int[] arr){
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
}

5.总结

归并排序是稳定排序,
可用于链式结构,且不需要附加存储空间,但递归实现时仍需要开辟相应的递归工作栈。

猜你喜欢

转载自blog.csdn.net/rjgcszlc/article/details/79751392