赞
踩
归并排序是利用归并思想实现的排序,采用分治策略,将问题分成各个部分,然后将各个部分的到的答案合并到一起,继而治之。
思路及流程如下图:
如上图所示,将分后的元素进行排序组合,可以创建一个临时数组,假设采取从小到大的方式排序,比较指针i指向的元素的值和指针j指向的值,若j指针指向的元素的值较小,则将其加入temp中,接着j和t指针向后移动,代码如下:
- //治,合并相邻两个子序列,从小到大
- public static void merge(int[] arr, int left, int mid, int right, int[] temp){
- //i指针指向左边有序序列的初始索引
- int i = left;
- //j指针指向右边有序序列的初始索引
- //因为arr的长度可能是奇数,所以mid + 1
- int j = mid + 1;
- //指向temp当前索引
- int t = 0;
- //使temp中的元素有序
- while (i <= mid && j <= right){
- //如果i指向元素的值小于j指向的元素的值
- //temp[t] = arr[i],t和i再分别后移
- if (arr[i] <= arr[j]){
- temp[t++] = arr[i++];
- } else {
- temp[t++] = arr[j++];
- }
- }
- //如果满足条件表示还有元素未加入temp中
- while (i <= mid){
- temp[t++] = arr[i++];
- }
- while (j <= right){
- temp[t++] = arr[j++];
- }
- //重置t,将temp中的元素拷贝到arr中
- t = 0;
- int tempLeft = left;
- while (tempLeft <= right){
- arr[tempLeft++] = temp[t++];
- }
- }
- }
分的步骤如图:
因为需要经过多次分治,所以可以使用递归解决。
- public class MergeSort {
- public static void main(String[] args) {
- int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
- int[] temp = new int[arr.length];
- System.out.println("排列前的结果为:" + Arrays.toString(arr));
- mergeSort(arr, 0, arr.length - 1, temp);
- System.out.println("排列后的结果为:" + Arrays.toString(arr));
- }
- public static void mergeSort(int[] arr, int left, int right, int[] temp){
- //结束条件
- if (left < right) {
- int mid = (left + right) / 2;
- //处理左边
- mergeSort(arr, left, mid, temp);
- //处理右边
- mergeSort(arr, mid + 1, right, temp);
- //归并
- merge(arr, left, mid, right, temp);
- }
- }
-
- /**
- *
- * @param arr 数组
- * @param left 初始索引
- * @param mid 中间索引
- * @param right 最后索引
- * @param temp 临时数组
- */
- //治,合并相邻两个子序列,从小到大
- public static void merge(int[] arr, int left, int mid, int right, int[] temp){
- //i指针指向左边有序序列的初始索引
- int i = left;
- //j指针指向右边有序序列的初始索引
- //因为arr的长度可能是奇数,所以mid + 1
- int j = mid + 1;
- //指向temp当前索引
- int t = 0;
- //使temp中的元素有序
- while (i <= mid && j <= right){
- //如果i指向元素的值小于j指向的元素的值
- //temp[t] = arr[i],t和i再分别后移
- if (arr[i] <= arr[j]){
- temp[t++] = arr[i++];
- } else {
- temp[t++] = arr[j++];
- }
- }
- //如果满足条件表示还有元素未加入temp中
- while (i <= mid){
- temp[t++] = arr[i++];
- }
- while (j <= right){
- temp[t++] = arr[j++];
- }
- //重置t,将temp中的元素拷贝到arr中
- t = 0;
- int tempLeft = left;
- while (tempLeft <= right){
- arr[tempLeft++] = temp[t++];
- }
- }
- }
- 排列前的结果为:[8, 4, 5, 7, 1, 3, 6, 2]
- 排列后的结果为:[1, 2, 3, 4, 5, 6, 7, 8]
还在学习中,有问题辛苦指出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。