[排序算法]-拿捏归并排序法

基本介绍

递归加合并,先分解后合并。

——爱因斯坦

核心思想

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

实例讲解

主要思路

  • 当左侧下标小于右侧下标时,求得中间位置索引,然后向其左右两侧递归排序,最终将排序的结果合并到一起。
  • 重点是两个有序的子序列合并到一个有序序列:定义临时数组用于存放合并后的有序序列,然后将临时数组的结果赋值回原来的数组中。具体为定义三个指针分别指向子序列1,子序列2,临时数组,然后同时相同访问两个子序列,每次两两比较将值小的那个放入到临时数组中,然后指针往后移动,继续两个序列中的对应值两两比较,直到某一个子序列的元素全部放入到了临时数组中为止,此时将另一个有序子序列的其他元素放入到临时数组即可,最终将临时数组的所有元素拷贝回原数组即可。
  • 结合代码,更易消化。

图示演示

动图演示

在这里插入图片描述

总体思路图示

在这里插入图片描述

子序列合并过程图示

在这里插入图片描述
在这里插入图片描述

代码实现

Talk is cheap, show me the code.

import java.io.*;
import java.util.*;

// Author:Peiliang Gong
// MergeSort.

class Sort
{   
    //main function
	public static void main (String[] args) throws java.lang.Exception
	{
		int[] arr = {3,-1,56,0,0,0,7,-3,2,-4};
		int[] temp = new int[arr.length];
		mergeSort(arr, 0, arr.length-1,temp);
		System.out.println("排序后的结果为:"+Arrays.toString(arr));
		
	}
	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){
	    // i指向左边有序序列起始位置,j指向右边有序序列起始位置,t索引临时数组的位置
	    int i = left;
	    int j = mid+1;
	    int t = 0;
	    //依次扫描两个有序序列,将小的一个加入到临时数组内
	    while(i <= mid && j <= right){
	        if(arr[i] <= arr[j]){
	            temp[t] = arr[i];
	            i++;
	        }else{
	            temp[t] = arr[j];
	            j++;
	        }
	        t++;
	    }
	    //将有序数组中剩余的元素加入到临时数组中
	    while(i <= mid){
	        temp[t] = arr[i];
	        i++;
	        t++;
	    }
	    while(j <= right){
	        temp[t] = arr[j];
	        j++;
	        t++;
	    }
	 	//将临时数组的元素重新赋值给原始数组,注意每次不是将所有的数都赋值回去,是将当前排序好的结果赋值回原来数组对应位置
	    int tempLeft = left;
	    t = 0;
	    while(tempLeft <= right){
	        arr[tempLeft] = temp[t];
	        tempLeft++;
	        t++;
	    }
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值