单链表的节点数,合并,相交,反转

Posted 等风来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单链表的节点数,合并,相交,反转相关的知识,希望对你有一定的参考价值。

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;
    }
}

 

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

以上是关于单链表的节点数,合并,相交,反转的主要内容,如果未能解决你的问题,请参考以下文章

看了有助于你面试的单链表的OJ面试题

几道简单的链表题

java 数据结构常考的OJ 链表,重点!重点!!!

408数据结构与算法—单链表的基本操作

链表14:单链表的排序

5种常见的链表基本操作