归并排序--图文演示,Java代码实现,附每一步详细注释

在这里插入图片描述

1.什么是归并排序?

1.1 算法原理
归并排序是创建在归并操作上的一种有效排序算法(稳定),速度仅次于快速排序。

1.2.基本思想
归并排序其实就是分治思想,分治模式在每一层递归上有2个步骤

  • 分 :将n个元素分为含n/2个元素的2个子序列(若n>1,则一直切分,直到n=1)

  • 治 : 用合并排序法分别对两个子序列进行递归的排序,然后合并已经排序好的子序列。

  • 可以理解为从上到下,再从下到上,分–排序–合。

算法步骤(如何合并2个子序列):

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤 3 直到某一指针达到序列尾;
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

3.复杂度分析
平均时间复杂度:O(nlogn)
最好时间复杂度:O(n)
最差时间复杂度:O(nlogn)
空间复杂度:O(n)
排序方式:就地排序
稳定性:稳定

4.Java实现

public class Solution{
	public static void merge_sort(int[] arr) {
    	merge_sort_recursive(arr, 0, arr.length-1);
	}
	public void merge_sort_recursive(int[] arr,int left,int right){
	        if(left>=right)return;
	        int mid=(left+right)/2;
	        merge_sort_recursive(arr,left,mid);
	        merge_sort_recursive(arr,mid+1,right);
	        meger(arr,left,mid,right);
	    }    
	public void meger(int [] arr,int left,int mid,int right){
	        int[] result=new int [arr.length];//创建临时数组,用于存储归并后的元素,临时数组的大小和原数组一样大。
	        int start1=left,end1=mid,start2=mid+1,end2=right;
	        int k=left;  //创建游标
	        while(start1<=end1&&start2<=end2){  //将两个子序列进行排序,并且存储到临时数组中
	            if(arr[start1]<arr[start2]){
	                result[k++]=arr[start1++];
	            }else{
	                result[k++]=arr[start2++];
	            }
	        }
	        while(start1<=end1){
	            result[k++]=arr[start1++];
	        }
	        while(start2<=end2){
	             result[k++]=arr[start2++];
	        }
	
	        for(k=left;k<=right;k++){  //将临时数组中的元素再复制到数组中
	            arr[k]=result[k];      //游标k的作用在此处,用于复制
	        }
	        
    }
	
	}
}

感谢您的阅读,如有疑问请在下方评论区提出,作者期待和您一起讨论学习,您的点赞和评论是对作者最大的支持!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
归并排序是一种经典的排序算法,它采用分治的思想,将待排序的数组不断地分割成小的子数组,然后再将这些子数组合并成一个有序的数组。下面是归并排序Java代码注释: ```java public class MergeSort { // 归并排序入口函数 public static void mergeSort(int[] arr) { int[] temp = new int[arr.length]; // 创建一个临时数组用于存储排序结果 mergeSort(arr, 0, arr.length - 1, temp); // 调用递归函数进行归并排序 } // 递归函数,实现归并排序 private 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); // 合并左右两部分 } } // 合并函数,将两个有序的子数组合并成一个有序的数组 private static void merge(int[] arr, int left, int mid, int right, int[] temp) { int i = left; // 左子数组的起始位置 int j = mid + 1; // 右子数组的起始位置 int k = 0; // 临时数组的起始位置 // 将左右两个子数组中较小的元素依次放入临时数组中 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } // 将剩余的元素依次放入临时数组中 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 将临时数组中的元素复制回原数组 for (int m = 0; m < k; m++) { arr[left + m] = temp[m]; } } } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值