《归并排序》——Java实现

这次的代码是在一篇博客找到的,忘记是哪个了,所以原主人希望指出转载的话,请联系。

归并排序是用了分治的思想,就是将大问题不断拆分成与原问题相同但是规模更小的问题,当将每个小问题都解决后,大问题自然就解决了。

在排序中,是将数组拆成两部分,然后将这两个部分继续拆分,直到拆成一个,因为一个元素默认就是有序的了,然后开始合并,两两合并,合并的时候两组排序,最后就是合并成功,数组有序。

平均时间复杂度是O(n log n),不过这个需要额外的空间作中转,所以还有空间复杂度是O(n)。

复制代码
 1 public class MergeSort implements IArraySort{
 2 
 3     @Override
 4     public int[] sort(int[] arr) {
 5         // 复制数组,不对入参修改
 6         int[] newArr = Arrays.copyOf(arr, arr.length);
 7 
 8         int[] t = new int[newArr.length];
 9         mergeSort(newArr,0,newArr.length-1,t);
10         return newArr;
11     }
12 
13     //分+合方法
14     public void mergeSort(int[] arr, int left, int right, int[] temp) {
15         if(left < right) {
16             int mid = (left + right) / 2; //中间索引
17             //向左递归进行分解
18             mergeSort(arr, left, mid, temp);
19             //向右递归进行分解
20             mergeSort(arr, mid + 1, right, temp);
21             //合并
22             merge(arr, left, mid, right, temp);
23 
24         }
25     }
26 
27     //合并的方法
28     /**
29      *
30      * @param arr 排序的原始数组
31      * @param left 左边有序序列的初始索引
32      * @param mid 中间索引
33      * @param right 右边索引
34      * @param temp 做中转的数组
35      */
36     public void merge(int[] arr, int left, int mid, int right, int[] temp) {
37 
38         int i = left; // 初始化i, 左边有序序列的初始索引
39         int j = mid + 1; //初始化j, 右边有序序列的初始索引
40         int t = 0; // 指向temp数组的当前索引
41 
42         //(一)
43         //先把左右两边(有序)的数据按照规则填充到temp数组
44         //直到左右两边的有序序列,有一边处理完毕为止
45         while (i <= mid && j <= right) {//继续
46             //如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
47             //即将左边的当前元素,填充到 temp数组
48             //然后 t++, i++
49             if(arr[i] <= arr[j]) {
50                 temp[t] = arr[i];
51                 t += 1;
52                 i += 1;
53             } else { //反之,将右边有序序列的当前元素,填充到temp数组
54                 temp[t] = arr[j];
55                 t += 1;
56                 j += 1;
57             }
58         }
59 
60         //(二)
61         //把有剩余数据的一边的数据依次全部填充到temp
62         while( i <= mid) { //左边的有序序列还有剩余的元素,就全部填充到temp
63             temp[t] = arr[i];
64             t += 1;
65             i += 1;
66         }
67 
68         while( j <= right) { //右边的有序序列还有剩余的元素,就全部填充到temp
69             temp[t] = arr[j];
70             t += 1;
71             j += 1;
72         }
73 
74 
75         //(三)
76         //将temp数组的元素拷贝到arr
77         //注意,并不是每次都拷贝所有
78         t = 0;
79         int tempLeft = left; 
82         while(tempLeft <= right) {
83             arr[tempLeft] = temp[t];
84             t += 1;
85             tempLeft += 1;
86         }
87 
88     }
89 }
复制代码

 

posted @   huang1993  阅读(66)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示