归并排序

/**
 * Project Name:Algorithm
 * File Name:MergeSort.java
 * Package Name:
 * Date:2017年9月22日上午8:53:15
 * Copyright (c) 2017, chenzhou1025@126.com All Rights Reserved.
 *
 */

/**
 * ClassName:MergeSort 
 * Function: 归并排序。测试数据:6 5 2 1 4 3 8 7 
 * Reason:     (1)归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略
 *             (分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
 *             (2)归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。
 *                 java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。
 *                      从上文的图中可看出,每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。
 *                     总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。
 *                      需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
 * Date:     2017年9月22日 上午8:53:15 
 * @author   michael
 * @version  
 * @since    JDK 1.7
 * @see      
 */
public class MergeSort {
    public static int number=0;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = "";
        while (sc.hasNext()) {
            input = sc.nextLine();
            System.out.println("输入值:" + input);
            long startTime = System.currentTimeMillis();
            String[] str = input.split(" ");
            int[] arr = new int[str.length];
            // 字符串数组转化成int数组
            for (int i = 0; i < str.length; i++) {
                arr[i] = Integer.parseInt(str[i]);
            }
            //归并排序开始
            sort(arr);
            
            long endTime = System.currentTimeMillis();
            System.out.println();
            System.out.println();
            System.out.println("最终排序结果:");
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[j]);
            }
            System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
        }
    }
    public static void sort(int arr[]){
        //在排序前,先创建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
        int[] temp = new int[arr.length];
        sort(arr,temp,0,arr.length-1);
    }
    public static void sort(int[] arr, int[] temp ,int left, int right){
        if(left>=right){
            return;
        }
        int mid = (left+right)/2;
        //左边归并排序,使得左子序有序
        sort(arr,temp,left,mid);
        //右边归并排序,使得右子序有序
        sort(arr,temp,mid+1,right);
        //将两个有序子序列合并
        merge(arr,temp,mid,left,right);
        System.out.print("第"+(++number)+"次循环结果:");
        for (int k = 0; k < temp.length; k++) {
            System.out.print(arr[k]);
        }
        System.out.println();

    }
    public static void merge(int[] arr, int[] temp, int mid, int left, int right){
        //左序列指针
        int i = left;
        //右序列指针
        int j = mid+1;
        //临时数组指针
        int t = 0;
        while(i<=mid&&j<=right){
            if(arr[i]<=arr[j]){
                temp[t++] = arr[i++];
            }else{
                temp[t++] = arr[j++];
            }
        }
        //将左边剩余元素填充进temp中
        while(i<=mid){
            temp[t++]=arr[i++];
        }
        //将右序列剩余元素填充进temp中
        while(j<=right){
            temp[t++]=arr[j++];
        }
        t = 0;
        //将temp中的元素全部拷贝到原数组中
        while(left<=right){
            arr[left++] = temp[t++];
        }


    }
}

 

posted on 2017-09-22 10:01  Michael2397  阅读(151)  评论(0编辑  收藏  举报

导航