前端复习--归并排序

起因,昨天取面试猿题库,两个面试官,每人各只考了两道算法题.

其中有一道是考归并排序不使用递归或是栈结构实现,感觉手生,当时答得并不好,傻傻地问面试官,不能考个"快排"吗,面试官笑笑:"快排"太简单....

1 传统方法,利用递归

归并排序其实要做两件事:

(1)“分解”——将序列每次折半划分

(2)“合并”——将划分后的序列段两两合并后排序

真的就只有这两件事.

我们先去解决"合并":   将两个有序数组,合并为一个.

    function merge(arr1,arr2){   //代码思想,是借用<剑指offer>中合并两个有序单链表
        if(!Array.isArray(arr1) || !Array.isArray(arr2)){
            return;
        }
        var result = [];
        function mergeInner(arr1,arr2){
            if(arr1.length == 0){
                result = result.concat(arr2);
                return;
            }else if(arr2.length == 0){
                result = result.concat(arr1);
                return;
            }

            if(arr1[0] < arr2[0]){
                result.push(arr1.shift());
                mergeInner(arr1,arr2);
            }else{
                result.push(arr2.shift());
                mergeInner(arr1,arr2);                
            }
        }
        mergeInner(arr1,arr2);
        return result;       
    }

有了上述基础之后,我们开始构思如何将一个数组分解成两个部分:

经过在指上演算,我们确定 var mid = Math.floor((arr.length-1)/2);

    function mergeSort(arr){
        if(arr.length == 1){
            return arr;
        }
        var mid = Math.floor((arr.length-1)/2);
        var left = arr.slice(0,mid+1);
        var right = arr.slice(mid+1);

        return merge(mergeSort(left), mergeSort(right));
    }


2 不使用递归

参考http://book.51cto.com/art/201108/287079.htm  这个网站的算法图示很好,能帮助理解

非递归并归排序的第一步:非递归地合并两个有序数组

思路:代码自己解释自己好了,js代码本来就是那么简单

       function merge(arr1,arr2){           
		if(typeof arr1 == "number"){
			arr1 = [arr1];
		}
		if(typeof arr2 == "number"){
			arr2 = [arr2];
		}
		var result = [];
		while(arr1.length!=0 && arr2.length!=0){
			if(arr1[0]<arr2[0]){
				result.push(arr1.shift());
			}else{
				result.push(arr2.shift());
			}
		}
		if(arr1.length==0){
			return result.concat(arr2);
		}else if(arr2.length==0){
			return result.concat(arr1);
		}		
	}
思路:我还是不想解释,程序员真的懒得写注释啊。。。

	function mergeSort(arr){
		while(arr.length != 1){
			var temp = [];
			if(arr.length%2==0){
		        for(var i=0;i<arr.length;i+=2){
		            temp.push(merge(arr[i],arr[i+1]));          
		        } 
		    }else{
		        for(var i=0;i<arr.length-1;i+=2){
		            temp.push(merge(arr[i],arr[i+1]));
		        }
		        temp.push(arr[arr.length-1]);
		    } 
		    arr = temp;
		}
		return arr[0];
	}

	console.log(mergeSort([1,2,5,3,4]));  //通过!!!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值