merge sort二刷

推荐答案

 1 public class Solution {
 2   public int[] mergeSort(int[] array) {
 3     // Write your solution here.
 4     if(array != null && array.length != 0) {
 5       int[] helper = new int[array.length];
 6       
 7       divide(array, helper, 0, array.length - 1);
 8     }
 9     
10     return array;
11   }
12   
13   private void divide(int[] array, int[] helper, int left, int right) {
14     if(left == right) {
15         return;
16     }
17     int mid = left + (right - left) / 2;
18     divide(array, helper, left, mid);
19     divide(array, helper, mid + 1, right);
20     merge(array, helper, left, mid, right);
21   }
22   
23   private void merge(int[] array, int[] helper, int left, int mid, int right) {
24     for (int i = left; i <= right; i++) {
25         helper[i] = array[i];
26     }
27     int leftIndex = left;
28     int rightIndex = mid + 1;
29     while (leftIndex <= mid && rightIndex <= right) {
30       if(helper[leftIndex] <= helper[rightIndex]) {
31           array[left++] = helper[leftIndex++];
32       } else {
33           array[left++] = helper[rightIndex++];
34       }
35     }
36     
37     while(leftIndex <= mid) {
38         array[left++] = helper[leftIndex++];
39     }
40   }
41 }
View Code

二刷代码

 1 public class Solution {
 2   public int[] mergeSort(int[] array) {
 3     // Write your solution here
 4     
 5     if (array != null && array.length != 0) {
 6         divide(array, 0, array.length - 1);
 7     }
 8     
 9     return array;
10   }
11   
12   private void divide(int[] array, int left, int right) {
13     if (left == right) {
14         return;
15     }
16     
17     int mid = left + (right - left) / 2;
18     divide(array, left, mid);
19     divide(array, mid + 1, right);
20     merge(array, left, right, mid);
21   }
22   
23   private void merge(int[] array, int left, int right, int mid) {
24     // 此处是主要问题,第一是每次都费时创建了新helper对象,第二是每次都重复拷贝了所有的array元素
25     // 知道helper应该只是用于存储当前merge所用到的元素,不过还没弄清应该如何设置拷贝的开始与结
26     // 束端,需记住merge阶段传入的left即为左端,right即为右端,mid将从left到right的部分array
27     // 划分为两部分,这被划分的两部分即为需要被merge排序的两个数组
28     int[] helper = new int[array.length];
29     for (int i = 0; i < array.length; i++) {
30         helper[i] = array[i];
31     }
32     int i = left;
33     int j = mid + 1;
34     int k = left; // 不需要专门设置个k,可以直接使用left,用于对array进行操作
35     
36     while (i <= mid && j <= right) {
37         if (helper[i] < helper[j]) {
38           array[k] = helper[i];
39         i++;
40       } else {
41           array[k] = helper[j];
42         j++;
43       }
44       k++;
45     }
46     
47     while (i <= mid) {
48         array[k++] = helper[i++];
49     }
50     // 此处费时将剩余的helper的最右部分拷贝到array,需注意到merge是从左到右重写部分array,而且
51     // helper就是部分array的拷贝,因此如果j指针未移动到right,j到right部分的helper和array是完全
52     // 相同而且是已经排序好的,因此不需要拷贝剩余的helper的最右部分到array
53     while (j <= right) {
54         array[k++] = helper[j++];
55     }
56   }
57 }

 

posted @ 2018-03-29 11:38  钲添  阅读(77)  评论(0)    收藏  举报