归并排序
/** * 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) 编辑 收藏 举报