归并排序实现(递归与非递归)

归并排序实现原理的个人理解
将数组不断等分成一个个小数组,再对每个小数组进行排序合并成一个新的有序数组。特点:稳定,当元素相同时不移动元素的位置,按照输入顺序来排,比较次数一般少于快排,移动次数一般多于快排

JavaScript递归实现:

function merge(left, right){
    var result = [];
    while(left.length > 0 && right.length>0){
        if(left[0] < right[0]){
            result.push(left.shift());
        }else{
            result.push(right.shift());
        }
    }
    return result.concat(left).concat(right);   //其中某个数组为空了,将剩下的接入
}
function sort(item){
    if(item.length == 1)
        return item;
    var middle = Math.floor(item.length / 2),
    left = item.slice(0, middle),
    right = item.slice(middle);
    return merge(sort(left), sort(right));  //递归将每个元素都分别成对排序了
}
var num = [1,15,74,65,23,6];
console.log(sort(num));

java递归实现:


public class MergeSort {
	public static int[] MergeSort(int[] nums, int l, int h) { 	//i,h便于后面递归的时候分裂数组
		if(l==h) {	//传入数组的首尾两个下标
			return new int[] {nums[l]};	//??
		}
		int mid = (l+h)/2;
		int[] left = MergeSort(nums, l, mid);	//分裂数组,对每个小数组进行排序
		int[] right = MergeSort(nums, mid+1, h);
		int[] newNum = new int[left.length + right.length];
		int m = 0, i = 0, j = 0;
		while(i!=left.length && j != right.length) {
			newNum[m++] = left[i] < right[j] ? left[i++] : right[j++]; 
		}
		//将剩下的一个非空数组全放入新数组中
		while( i < left.length) {
			newNum[m++] = left[i++];
		}
		while(j < right.length) {
			newNum[m++] = right[j++];
		}
		return newNum;
	}
	public static void main(String[] args) {
		int [] nums = new int[]{1,65,75,23};
		int [] newNums = MergeSort(nums, 0, nums.length-1);
		for(int item : newNums) {
			System.out.println(item);
		}
	}
}

java非递归实现


public class MergeSort {
	public static int[] MergeSort(int[] nums) { 
		int step = 1;
		int len = nums.length;
		int [] temp = new int[len];
		while(step<len) {
			int i = 0;
			int left,right,lTop,rTop;	//设置左右数组边界
			while(i<len) {
				left = i;
				lTop = i + step - 1;
				right = lTop + 1;
				if(right + step - 1 > len -1) {
					rTop = len - 1;
				}else {
					rTop = right + step - 1;
				}
				//将每个小数组分别排序
				int p = left;	//左数组下标
				int q = right;	//右数组下标
				int k = left;	//临时存储数组的下标
				while(p<=lTop && q <=rTop) {	//排序插入临时数组
					if(nums[p] <= nums[q]) {
						temp[k++] = nums[p++];
					}else {
						temp[k++] = nums[q++];
					}
				}
				//将多余的数组元素塞进去
				while(p<=lTop) {
					temp[k++] = nums[p++];
				}
				while(q<=rTop) {
					temp[k++] = nums[q++];
				}
				for(int j = left; j <= rTop; j++) {
					nums[j] = temp[j];
				}
				i+=2*step ;		//进行下一批的左右数组排序
			}
			step = 2*step;	//扩大一倍排序数组的大小,相当于将小数组合并了
		}
		return nums;
	}
	public static void main(String[] args) {
		int [] nums = new int[]{1,6,4};
		int [] newNums = MergeSort(nums);
		for(int item : newNums) {
			System.out.println(item);
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值