JAVA代码实现归并排序

归并排序

归并排序用到了分治法的思想。用代码实现时,按从小到大排序为例,主要的思路分为分解和合并两大步骤:
分解:

  1. 第一次分解时,根据数组的头尾下标,得出分界线的位置,即:mid=(left+right)/2;
  2. 向左递归分解:就是将数组的头下标和分界线的下标当做新序列的头尾下标再次分解;
  3. 向右递归分解:就是将分界线的下标后一位(mid+1)和数组的尾下标当做新序列的头尾下标再次分解;
  4. 分解结束后(即头尾相等时)开始合并操作。

合并:

  1. 初始化左边序列的开始下标:i=left;右边序列的开始下标:j=mid+1;
  2. 左右下标对应的当前值依次比较,将较小的值放入临时数组中,然后每次从较小值的那边开始继续移动下标;
  3. 第2步操作结束后会出现三种情况:1)左右序列的数据全部放入临时数组中了;2)左边序列还剩数据没有放入临时数组中;3)右边序列还剩数据没有放入临时数组中。考虑后两种情况,将剩下的数据复制到临时数组中;
  4. 将临时数组复制到原始数组。

上述如有错误之处,还望指出,我会及时改正。其代码如下:

package com.sort.mergetSort;

import java.util.Arrays;

public class MergeSortDemo2 {

	public static void main(String[] args) {
		int array[] = { 8, 4, 5, 7, 1, 3, 6, 2 };
		int temp[] = new int[array.length];// 归并排序需要一个额外空间
		System.out.println("排序前:" + Arrays.toString(array));
		mergeSort(array, 0, array.length - 1, temp);
		System.out.println("排序后:" + Arrays.toString(array));

	}

	/**
	 * 归并排序
	 * 
	 * @param array
	 * @param left
	 * @param right
	 * @param temp
	 */
	public static void mergeSort(int[] array, int left, int right, int[] temp) {
		if (left >= right) {
			return;
		}
		int mid = (left + right) / 2;
		// 向左递归分解
		mergeSort(array, left, mid, temp);
		// 向右递归分解
		mergeSort(array, mid + 1, right, temp);
		// 合并
		merge(array, left, mid, right, temp);
	}

	/**
	 * 合并操作
	 * 
	 * @param array 原始数组
	 * @param left  左边有序序列的初始下标
	 * @param mid   中间值的下标 ,分界线
	 * @param right 最右边下标
	 * @param temp  临时数组
	 */
	public static void merge(int[] array, int left, int mid, int right, int[] temp) {
		// 1.定义左边序列和右边序列开始下标
		int i = left;
		int j = mid + 1;
		int t = 0;// 记录临时数组的下标
		// 2.比较左右两个序列中的值
		while (i <= mid && j <= right) {
			// 2.1如果左边序列的当前值小于等于右边序列的当前值,就将左边序列当前值暂存在临时数组
			if (array[i] <= array[j]) {
				temp[t] = array[i];
				t++;
				i++;
			} else {// 2.2反之,如果右边序列的当前值大于左边序列的当前值,就将右边序列的当前值暂存在临时数组
				temp[t] = array[j];
				t++;
				j++;
			}
		}
		// 3.上面循环结束时,可能会出现两种情况
		// 3.1右边序列遍历完了,但是左边序列还剩数据
		while (i <= mid) {
			temp[t] = array[i];
			t++;
			i++;
		}
		// 3.2左边序列遍历完了,右边序列还剩数据
		while (j <= right) {
			temp[t] = array[j];
			t++;
			j++;
		}
		// 4.数据全部放到临时数组后,开始将temp复制给array
		// 4.1.下标位置重新置为0
		t = 0;
		// 4.2.定义array数组的下标,每次从left开始放
		int tempLeft = left;
		// 4.3.开始复制数组
		while (tempLeft <= right) {
			array[tempLeft] = temp[t];
			tempLeft++;
			t++;
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值