归并排序

归并排序介绍

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

归并排序思想示意图

1-基本思想:
 

 

 

 2-合并相邻有序子序列:

再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤

 

 代码实现

1. public class mergesort {  
2.     public static void main(String[] args) {  
3.         int[] arr = {8, 4, 4, -4, 1, 3, 6, 2};  
4.         int[] temp = new int[arr.length];  
5.         System.out.println("原数组为:" + Arrays.toString(arr));  
6.         mergeSort(arr, 0, arr.length - 1, temp);  
7.         System.out.println("排序后数组为:" + Arrays.toString(arr));  
8.     }  
9.   
10.     /** 
11.      * 分+合方法 
12.      * @param arr   需要排序的数组 
13.      * @param left  左边有序序列的初始索引 
14.      * @param right 右边索引 
15.      * @param temp  做中转的数组 
16.      */  
17.     private static void mergeSort(int[] arr, int left, int right, int[] temp) {  
18.         if (left < right) {  
19.             int mid = (left + right) / 2;//中间索引  
20.             mergeSort(arr, left, mid, temp);//向左递归进行分解  
21.             mergeSort(arr, mid + 1, right, temp);//向右递归进行分解  
22.   
23.             merge(arr, left, mid, right, temp);//合并  
24.         }  
25.     }  
26.   
27.     //合并的方法  
28.     private static void merge(int[] arr, int left, int mid, int right, int[] temp) {  
29.         int i = left;//标记第一个子数组的最左端 .初始化 i,  左边有序序列的初始索引  
30.         int j = mid + 1;//标记第二个子数组的最左端. 初始化 j, 右边有序序列的初始索引  
31.         int t = 0;// 指向 temp 数组的当前索引  
32.   
33.         //(一)  
34.         //先把左右两边(有序)的数据按照规则填充到 temp 数组  
35.         //直到左右两边的有序序列,有一边处理完毕为止  
36.         while (i <= mid && j <= right) {  
37.             //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素  
38.             //即将左边的当前元素,填充到 temp 数组  
39.             //然后 t++, i++  
40.             if (arr[i] <= arr[j]) {  
41.                 temp[t] = arr[i];  
42.                 i++;  
43.                 t++;  
44.             } else {  
45.                 temp[t] = arr[j];//反之,将右边有序序列的当前元素,填充到 temp 数组  
46.                 j++;  
47.                 t++;  
48.             }  
49.         }  
50.   
51.         //(二)  
52.         //把有剩余数据的一边的数据依次全部填充到 temp  
53.         while (i <= mid) {  
54.             temp[t] = arr[i];  
55.             i++;  
56.             t++;  
57.         }  
58.         while (j <= right) {  
59.             temp[t] = arr[j];  
60.             j++;  
61.             t++;  
62.         }  
63.   
64.         //(三)!!!!重点理解  
65.         //将 temp 数组的元素拷贝到 arr  
66.         //注意,并不是每次都拷贝所有  
67.         int templeft = left;  
68.         //例如:  
69.         //第一次合并 tempLeft = 0 , right = 1  
70.         //第二次:tempLeft = 2,right = 3 //第三次: tL=0 ri=3.....  
71.         //最后一次 tempLeft = 0 right = 7  
72.         t = 0;  
73.         while (templeft <= right) {  
74.             arr[templeft] = temp[t];  
75.             t++;  
76.             templeft++;  
77.         }  
78.     }  
79. }  
posted @ 2020-11-02 15:57  白刃天使  阅读(103)  评论(0编辑  收藏  举报