javascript实现非递归--归并排序

news/2024/7/8 2:30:22

另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好。所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握。

这是我的实现代码

/*
     *
     * 非递归版归并排序,思路如下:
     * 至底而上的思路,二和一,四和一,最后是一半一半和整。
     * 循环从左到右依次执行,为了节省空间,我节省了右序列,将原数列的一部分作为右小序列,这一部分不会被覆盖。
     * 作者:吴伟欣
     * */
    function mergeSearch(arr)
    {
        var len = arr.length;
        var left_s,left_e,right_s,right_e;
        var left_list = null;   //只需要一半即可,节省空间,因为原数组后半段是不可能被覆盖的。
        for (var i = 1;i<len;i*=2)
        {
            var next = 0;//每一次合并以后初始化next
            for(left_s=0;left_s<len;left_s=right_e)
            {
                next = left_s;
                left_e = right_s = left_s + i;
                right_e = right_s + i;
                if(right_e > len)
                {
                    right_e = len;
                }
                //复制左边的数组
                left_list = arr.slice(left_s,left_e);
                var left_index = 0;
                var left_len = left_list.length;//空间换取时间
                while(left_index<left_len)       //归并代码
                {
                    if((right_s>=right_e)||(left_list[left_index]<=arr[right_s])) //短路逻辑,优化性能
                    {
                        arr[next++] = left_list[left_index++];
                    }else
                    {
                        arr[next++] = arr[right_s++];
                    }
                }
            }
        }
    }
    //测试代码
    var a = [3,7,1,2,10,9,1,6];
    var b = [10,9,8,2,7,10,10,10,9,9,9,8];
    mergeSearch(a);
    mergeSearch(b);
    alert(a);
    alert(b);

  运行结果还是正确的:

首先,归并思路应该不难写。我的思路是这样的,先整体思维是,很自然的从单个合并,然后在合并,最后合成一个整体。每次都是两两合并。细节方面是,合并的时候到底怎么做比较好呢,可以想象,我们可以创建一个整数列,然后合并的时候放进去,整条合并完,在给原来的,这当然是很笨的方式。我采用的是,每两个需要合并的子序列肯定是不可以在原数列的空间上进行排序,但是至少需要多少空间呢,你会发现,这两个序列的右边那个是不可能被覆盖,那意味着,这两个序列的右边序列是可以在原数列上玩,左序列我会每次创建空间,然后放进原数列。短路逻辑那里,是考虑到如果左边序列完全排序好了,那么右序列默认是在原序列上,并且排好序,所以很明显已经搞定,后面的是不需要在动了,直接进入下一个序列合并。整体最坏复杂度,应该是这样的,一个logn 和一个n循环,整体应该是nlogn

转载于:https://www.cnblogs.com/wuweixin/p/5313052.html


http://www.niftyadmin.cn/n/3376629.html

相关文章

如何在同一系统里同时启动多个Tomcat

需要在同一系统里启动多个tomcat,应该怎么处理? tomcat是个服务程序&#xff0c;需要占用几个通讯端口&#xff0c;所以默认情况是不能启动多个tomcat,如果要启动多个tomcat,需要修改配置文件&#xff0c;通过在配置文件设置不同的通讯端口就可以做到.文件 %TOMCAT_HOME%/conf…

Docker Swarm 让你事半功倍

2016 年 DockerCon &#xff08;天啊……我多么希望我当时在场&#xff09;上展示的最重大的变革之一就是 1.12 版本引擎的 Swarm 模式。它意味着什么呢&#xff1f;它意味着&#xff1a;如果你在运行 Docker 1.12时 &#xff0c;你就可以原生创建一个 Swarm 集群。 创建一个 s…

CSAcademy Beta Round #3 a-game

题目连接 a-game 大意&#xff1a;有一个只包含A和B的字符串&#xff0c;两个人分别取这个串的子串&#xff0c;但是每一次取不能与之前取到过的子串有交集&#xff0c;最后谁取到的所有串中A的总数量少的判为胜。如果一样&#xff0c;则为平手。 给出这样的字符串&#xff0c;…

(笔记)Linux内核学习(七)之内核同步机制和实现方式

一 原子操作 指令以原子的方式执行——执行过程不被打断。 1 原子整数操作 原子操作函数接收的操作数类型——atomic_t //定义 atomic_t v;//初始化 atomic_t u ATOMIC_INIT(0);//操作 atomic_set(&v,4); // v 4 atomic_add(2,&v); // v v 2 6 atomic_in…

剑指Offer(Java版):不用加减乘除做加法

2019独角兽企业重金招聘Python工程师标准>>> 题目&#xff1a;写一个函数&#xff0c;求两个整数之和&#xff0c;要求在函数体内不得适用&#xff0c;-&#xff0c;* &#xff0c;./ 四则运算符号 面试的时候被问道这个问题&#xff0c;首先我们分析人们是如何进行…

android开发之生命周期

android开发之生命周期 一&#xff1a;Activity的生命周期&#xff1a; 这几天了了解了安卓Activity的生命周期&#xff0c;对于生命周期有了大概的理解&#xff1b;一个Activity的生命周期也就是Activity从生成到运行&#xff0c;到登入其他界面时暂停&#xff0c;再到到当其他…

STM32F407应用笔记--使用之前的体会

这些天使用STM32F4系列的CPU设计项目&#xff0c;性能十分强大&#xff0c;ARM和DSP二核一&#xff0c;号称DSC。设计硬件之后&#xff0c;开始设计软件&#xff0c;大体有两个方向&#xff1a;一是使用库函数&#xff0c;二是使用实时操作系统。其它直接操寄存器的软件写法就避…

java smack 例子_关于JAVA利用smack连接openfire的jar依赖问题

一、GitHub上的maven依赖直接使用maven依赖二、关于smack-4.3.4的jar包相关依赖有两种方式①、引入maven依赖&#xff0c;比4.2.0版本多了一项②、可以在https://www.igniterealtime.org/downloads/download-landing.jsp?filesmack/smack-4.3.4.zip这里下载最新的4.3.4的smack…