算法笔记-----归并排序

归并排序

介绍

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

也就是该算法的核心思想是分治思想

动态图解

这里写图片描述

这里写图片描述我们发现我们的分并没有做什么其他的功能,只是将我们的数组拆分开来

为我们下面的治提供条件

我们再来看看他的复杂度,我们是8个数据,但是合并总共是7次

所以说他的复杂度是线性增长,不像其他的拍需要算法那样是平方增长

我们看最后一次合并做了什么

这里写图片描述

这里写图片描述

也就是说我们的归并排序是需要一个辅助数组的,这也是我们代码中最复杂的一部分

代码实现

package 数据结构;

import java.lang.reflect.Array;
import java.util.Arrays;

//归并排序
//@author  王庆华
public class MergetSort {
	public static void main(String[] args) {
		//创建数组
		int arr[] = {8,4,5,7,1,3,6,2};
		int temp[] = new int[arr.length];//归并排序需要一个额外的空间的
		megeSort(arr, 0, arr.length-1, temp);
		System.out.println("归并排序后"+Arrays.toString(arr));
		
	}
	
	//分解+合并方法 
	public static void megeSort(int[] arr,int left,int right, int[] temp){
		if(left<right){
			int mid = (left+right)/2;//中间索引
			//向左递归进行分解
			megeSort(arr, left, mid, temp);
			//向右递归分解
			megeSort(arr, mid+1, right, temp);
			//每分解一次就合并一次
			merge(arr, left, right, mid, temp);
		}
	}
	
	
	//合并的方法
	/**
	 * 
	 * @param arr   需要排序的初始的数组
	 * @param left 左边有序子序列的初始索引
	 * @param right  右边有序子序列的索引
	 * @param mid	中间索引
	 * @param temp	辅助数组
	 */
	public static void merge(int[] arr,int left,int right,int mid,int[] temp){
		int i = left;//初始化i   表示左边有序子序列的初始索引
		int j = mid + 1;//j是我们右边子序列的初始索引
		int t = 0;  //这个是我们辅助数组的当前索引,来帮助我们在那个地方插入值
		
		//(1)先把左右两边(有序)的数据按照规则填充到辅助数组temp中
		//直到左右两边的有序序列有一边处理完毕为止
		while(i <= mid && j <= right){
			if(arr[i] <= arr[j]){
				//左边有序子序列的当前元素<=右边有序序列的当前元素
				//左边的元素填充到辅助数组
				temp[t] = arr [i];
				t+=1;
				i+=1;
			}else{
				//反之就是右边进行拷贝操作
				temp[t] = arr[j];
				t+=1;
				j+=1;
			}
		}
		
		
		//(2)
		//把有剩余数据的一边,依次填充到辅助数组中
		while(i <= mid){
			//说明左边有序子序列有剩余元素
			temp[t] = arr[i];
			t+=1;
			i+=1;
		}
		while(j <= right){
			//右边有序子序列有剩余
			temp[t] = arr[j];
			t+=1;
			j+=1;
		}
		
		//(3)将辅助数组中的数据拷贝到arr中
		//注意并不是每一次都是拷贝所有的元素
		t = 0;
		int tempLeft = left;//
		while(tempLeft <= right){
			//第一次合并时  tempLeft=0 , right = 1
			//第二次			tempLeft = 2 riht = 3
			//最后一次tempLeft = 0 ,right = 7
			arr[tempLeft] = temp[t];
			t+=1;
			tempLeft+=1;
		}
	}
}

我们需要注意的是,拷贝数组的时候我们是用递归的,也就是说我们一开始是两个两个合并,所以辅助数组一开始不是直接拷贝8个数据的,也就是我们的tempLeft和right并不是0和7,而是0 1 2 3 然后合并成为0 3 也就是前四个数据,后面肯定会有4 7 合并,最后才是我们的0 7 整个数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会写代码的花城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值