并归排序(JAVA)

/**
 * 并归排序
 * 思路:首先使序列的每个子序列都有序(将序列打散成n个单个的序列,那么每个子序列必然有序),然后逐个二路并归,使子序列段间有序,
 * 不断并归,最终使真个序列有序
 * 过程:
 * 给出一个无序的序列
 * 1)如果序列的长度 <= 1,那么就不需要对序列进行排序
 * 2)如果序列的长度 >= 2, 对他的左半边进行递归排序,对他的右半边进行递归排序
 * 3)此时序列的左半边和右半边分别是一个已经排好序的序列,然后对这2个有序序列进行二路并归,合并成一个完整的有序序列
 * 4)排序完成
 * @author yinming.yu
 *
 */
public class MergeSort {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] data = {10, 45, 454, 5, 4, 1, 54, 5, 454, 5};
		//数组实现并归排序
		mregeSort(data, 0, data.length-1);
		for(int i : data){
			System.out.print(i+" ");
		}

	   
		

	}
	/**
	 * 单链表节点
	 * @author yinming.yu
	 *
	 */
	static class Node{
		int data;
		Node next;
		Node(){}
		Node(int data){
			this.data = data;
		}
	}
	/**
	 * 对一个序列指定区间内进行排序
	 * @param data 被排序序列
	 * @param left 区间的起始下标
	 * @param right 区间的终点下标
	 */
	public static void mregeSort(int[] data, int left, int right){
		if(data ==  null) return ;
		if(left >= right) return;//排序的起始点 >= 终点,不需要排序
		//以下情况需要排序
		//递归排序区间左边的序列,使其有序
		mregeSort(data, left, (left+right)/2);
		//递归排序区间右边的序列,使其有序
		mregeSort(data, (left+right)/2+1, right);
		//此时左右区间都有序,那么将2个有序的子序列二路并归成一个完整的有序序列
		merge(data, left, right);			
	}
	/**
	 * 将2个有序序列合并成一个有序序列
	 * 此时穿进去的数组必须是左半边有序,右半边有序
	 * @param data
	 * @param left
	 * @param right
	 */
	public static void merge(int[] data, int left, int right){
		if(data == null || data.length == 1) return;		
		//计算中间下标
		int midIndex = (left+right)/2;
		//左边[left, midIndex], 右边[mindIndex+1,right]
		//数组进行二路并归需要申请新的空间,而链表不需要
		int[] temp = new int[data.length];
		int tempIndex = left;//指向缓存数组的头部指针
		int leftIndex = left;//针指向左边序列头部指
		int rightIndex = midIndex+1;//指向右边序列头部指针
		while(leftIndex <= midIndex && rightIndex <= right){
			//取小的元素放入新的数组里边
			if(data[leftIndex] < data[rightIndex]){
				//左边当前指针元素小
				temp[tempIndex] = data[leftIndex];
				tempIndex++;
				leftIndex++;
			}else{
				//右边小
				temp[tempIndex] = data[rightIndex];
				tempIndex++;
				rightIndex++;
			}
		}
		//其中一个序列必然先遍历完成,导致退出循环,那么剩下的序列直接往新数组存即可
		while(leftIndex <= midIndex){
			//左边没有遍历完
			temp[tempIndex] = data[leftIndex];
			tempIndex++;
			leftIndex++;
		}
		while(rightIndex <= right){
			//右边没有遍历完
			temp[tempIndex] = data[rightIndex];
			tempIndex++;
			rightIndex++;
		}
		//缓存数组中已经将左右有序序列并归成一个有序序列,直接复制到原数组中去即可
		for(int i = left; i <= right; i++){
			data[i] = temp[i];
		}
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值