zoukankan      html  css  js  c++  java
  • 单链表的节点数,合并,相交,反转

    1.求节点数

    function getNodeNum(head){
        if(head == null){
            return 0;
        }
        var len = 0,
            cur = head;
        while(cur != null){
            len++;
            cur = cur.next;
        }
        return len;
    }

    2. 查找倒数第K个节点

    //可以统计节点个数,再找到第n-(k-1)个节点,最后一个节点的倒数第1个,倒数第K个节点是n-(k-1)
    //这里使用双指针法,两个指针,第一个指针先走到第k个节点,前后两个指针相差k-1,
    //这样两个指针一起走,首个指针走到最后一个节点,第二个节点指向倒数第k个节点
    function getLastKthNode(head,k){
        if(k == 0 || head == null){
            return null;
        }
        var ahead = head,
            behind = head;
        while(k > 1 && ahead != null){
            ahead = ahead.next;
            k--;
        }
        //说明链表长度不足k
        if(k > 1 || ahead == null){
            return null;
        }
        while(ahead.next != null){
            behind = behind.next;
            ahead = ahead.next;
        }
        return behind;
    }

    3.查找中间节点

    //用双指针法,快慢指针,慢指针每次一步,快指针每次两步,当快指针走到尾部,慢指针走到中间节点
    function getMiddleNode(head){
        if(head == null || head.next == null){
            return head;
        }
        var ahead = null,
            behind = null;
        while(ahead.next != null){
            ahead = ahead.next;
            behind = behind.next;
            if(ahead.next != null){
                ahead = ahead.next;
            }
        }
        return behind;
    }

    4. 合并两个有序链表为一个新的有序链表

    function mergeSortedList(head1,head2){
        if(head1 == null){
            return head2;
        }
        if(head2 == null){
            return head1;
        }
        var mhead = new Node();
        var h1 = head1.next,
            h2 = head2.next;
        if(h1.val < h2.val){
            mhead.next = h1;
            mhead.next.next = null;
            h1 = h1.next;
        }
        else{
            mhead.next = h2;
            mhead.next.next = null;
            h2 = h2.next;
        }
        var temp = mhead;
        while(h1 != null && h2 != null){
            if(h1.key < h2.key){
                temp.next = h1;
                h1 = h1.next;
                temp = temp.next;
                temp.next = null;
            }
            else{
                temp.next = h2;
                h2 = h2.next;
                temp = temp.next;
                temp.next = null;
            }
        }
        if(h1 != null){
            temp.next = h1;
        }
        else{
            temp.next = h2;
        }
        return mhead;
    }

    5.判断两个单链表是否相交

    //判断依据,两个单链表相交之后,其后面的链表是共有的,形成一个三条线共用一个顶点的形状
    //因此判断两个链表的最后一个点是否相同,即可判定是否有交点
    function IsIntersected(head1,head2){
        if(head1 == null || head2 == null){
            return false;
        }
        var tail1 = head1,
            tail2 = head2;
        while(tail1.next != null){
            tail1 = tail1.next;
        }
        while(tail2.next != null){
            tail2 = tail2.next;
        }
        return tail1 == tail2;
    }

    6.求两个链表的第一个交点

    //求两个链表的第一个交点,先判断是否相交,如果不相交,返回null,否则,将长度大的链表的指针
    //向前移动两个链表的长度差距离,这样两个链表指针距离交点的长度相等,两个指针同时向前移动,
    //当指针相同时候,即为第一个交点
    function getFirstCommonNode(head1,head2){
        if(head1 == null || head2 == null){
            return false;
        }
        var tail1 = head1,
            len1 = 0,
            tail2 = head2,
            len2 = 0;
        while(tail1.next != null){
            tail1 = tail1.next;
            len1++;
        }
        while(tail2.next != null){
            tail2 = tail2.next;
            len2++;
        }
        if(tail1 != tail2){
            return null;
        }
        var count = len1 - len2;
        count = Math.abs(count);
        tail1 = head1;
        tail2 = head2;
        if(count > 0){
            while(count--){
                tail1 = tail1.next;
            }
        }
        else{
            while(count--){
                tail2 = tail2.next;
            }
        }
        while(tail1 != tail2){
            tail1 = tail1.next;
            tail2 = tail2.next;
        }
        return tail1;
    }

    7.反转链表

    //从尾到头打印链表,对于颠倒顺序的问题,首先想到栈,先进后出,要么使用自定义栈,
    //要么使用系统栈,即递归
    function reverseTraverse(head){
        var stack = [];
        var cur = head;
        while(cur != null){
            stack.push(cur);
        }
        while(stack.length > 0){
            var node = stack.pop();
            console.log('val ' + node.val)
        }
    }
    //使用递归(系统栈,递归栈的思想)
    function reverseTraverse(head){
        //递归出口,出栈条件
        if(head == null){
            return;
        }
        else{
            reverseTraverse(head.next);
            //递归出口,即出栈时候,才会执行此句打印,所以是倒着打印
            console.log('val ' + head.val);
        }
    }
    //反转链表,利用头插法,将后面的节点不断插入到head节点后面
    function reverse(head){
        if(head == null || head.next == null){
            return;
        }
        var cur = head.next,
            next = cur.next;
        //第二个节点与第三个节点断开,否则会形成环
        cur.next = null;            
        while(next != null){
            cur = next;
            next = cur.next;
            cur.next = head.next;
            head.next = cur;
        }
    }
    //三个指针遍历,将链表就地反转,所有节点的next都反向指到前面
    function reverse(head){
        if(head == null || head.next == null){
            return head;
        }
        var pre,cur,next;
        pre = head;
        cur = head.next;
        head.next = null;
        //保存next指针,当前next反向,pre前移,cur前移
        while(cur.next != null){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        head = cur;
    return head; }

    参考:http://blog.csdn.net/luckyxiaoqiang/article/details/7393134

  • 相关阅读:
    [转载]为 Windows 下的 PHP 安装 PEAR 和 PHPUnit
    作品和案例
    js创建对象的最佳实践
    log4j的PatternLayout参数含义
    Java线程池——ThreadPoolExecutor的使用
    登录mysql 报 Access denied for user 'root'@'localhost' 错误
    CentOS 7下使用yum安装MySQL5.7
    linux下MySQL停止和重启
    Linux 命令 -- chown
    Linux 命令 -- chmod
  • 原文地址:https://www.cnblogs.com/mengff/p/6886753.html
Copyright © 2011-2022 走看看