分治_合并算法_排序_非递减(Java实现)

分治_合并算法实现数组排序(非递减)(Java实现)

分治_合并算法的思想就是 先将大的问题分为规模相近的两个小的问题,递归地将其再分为两个小问题,直至不可再分。然后将其合并,在合并过程中通过比较等方法将问题解决,将小的问题逐个解决后,再将它们合并起来,即可得到大问题的解。

下面以一道题目为例子介绍合并算法

给定一个包含n个元素的一维线性序列 ,对这n个元素按照非递减顺序排序。设 a[0:7] = {23,5,9,16,30,25,17,18},采用基于分治策略的合并排序算法解决该问题。

按照思想,我们需要将这个数组递归地分成两个数组,直至数组不可再分; 然后再通过比较,将数组合并,通过比较之后合并的数组都是有序的,所以最终得到的数组是有序的。

(图是自己画的,还不是很熟练,所以有点丑,以后多练习一下)
DivideAndMerge

下面附上解题代码:

package com.gduf.exer1;

/*
 * 给定一个包含n个元素的一维线性序列 ,对这n个元素按照非递减顺序排序。
 * 设 a[0:7] = {23,5,9,16,30,25,17,18},采用基于分治策略的合并排序算法解决该问题。
 */

public class DivideAndMerge {

	public static void MergeSort(int[] arr, int left, int right) {
		//left为起始位置,right为结束位置
		if (left < right) {
			int mid = (left + right) / 2;	//mid为二分位置
			MergeSort(arr, left, mid);	//前半部分
			MergeSort(arr, mid + 1, right);	//后半部分
			Merge(arr, left, mid, right);	//将数组合并
		}
	}

	/**
	 * @param: section1: 左边数组第一个元素的下标
	 * @param: section2: 左边数组最后一个元素,将section2+1可得右边数组第一个元素的下标
	 * @param: last: 右边数组的最后一个元素
	 */
	public static void Merge(int[] arr, int section1, int section2, int last) {
		int[] temp = new int[last - section1 + 1];	//声明一个临时数组,长度为要归并的数组的长度
		int i = section1;	//记住左边数组第一个元素的下标
		int j = section2 + 1;	//记住右边数组第一个元素的下标
		int k = 0;	//k用于记录临时数组下标
		while ((i <= section2) && (j <= last)) {
			//左边数组元素和右边数组元素比较,把小的元素赋给临时数组
			//每一次将数组的值赋给临时数组后都+1,临时数组获取值后也+1
			if (arr[i] <= arr[j]) {
				temp[k++] = arr[i++];
			} else {
				temp[k++] = arr[j++];
			}
		}
		/* 
		 * 若左侧或右侧在执行完上述代码后(即不满足while循环条件后)仍然还有数组未复制到
		 * 临时数组中,则执行下面的两个while语句,确保所有数组都会被复制到临时数组中,
		 * 并通过这样的过程,保证合并后的数组有序。
		 */
		 
		//把左边剩余的数组元素赋给临时数组
		while (i <= section2) {
			temp[k++] = arr[i++];
		}
		
		//把右边剩余的数组元素赋给临时数组
		while (j <= last) {
			temp[k++] = arr[j++];
		}
		
		//用临时数组元素覆盖原数组元素
		for (int count = 0; count < temp.length; count++) {
			arr[count + section1] = temp[count];
		}
	}

	public static void main(String[] args) {
		//原数组
		int[] arr = {23,5,9,16,30,25,17,18};
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
		System.out.println();
		MergeSort(arr, 0, arr.length - 1);// 从数组arr的0位到arr.length-1位排序
		//排序后
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值