链表

1.从尾到头打印链表

要注意区分while和if的区别:
while是个循环,只有条件为假才跳出循环
if只判断一次。

2.链表中倒数第k个节点

一般链表的问题我们都用双指针来解决。这个题主要要考虑健壮性。首先我们要判断头节点不为空,k>0。
其次在运行的过程中也要一直保证节点不为空
思路:求倒数第k个节点,其实就是第n-k+1个节点,可以写为n-(k-1)个节点。定义两个指针,快指针先走k-1步,之后慢指针才开始走。当快指针走到末尾时,慢指针走到了倒数第k个节点。
代码如下:
/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function FindKthToTail(head, k)
{
    if(head==null||k<0){
        return false;
    }
    var fast = head;
    var low = head;
    
    for(i=0;i<k;i++){
        if(fast!=null){
             fast = fast.next
        }else {
            return false;
        }
    }
    
    while(fast){
        fast = fast.next;
        low = low.next;
    }
    return low;
}

3.反转链表:输入一个链表,反转链表后,输出新链表的表头。

这里需要定义三个指针,分别指向结点的前一个结点,结点,结点的后一个节点。同时要注意判断鲁棒性。
(需要重做一遍,最后三个节点赋值那里一直不清楚)

4.合并两个排序的链表:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则

普通的递归。但是要注意链表为空的情况
function Merge(pHead1, pHead2)
{
    if(pHead1==null){
        return pHead2;
    }
    if(pHead2==null){
        return pHead1;
    }
    var result = {};
    if(pHead1.val<pHead2.val){
        result = pHead1;
        result.next = Merge(pHead1.next,pHead2)
    }else{
        result = pHead2;
        result.next = Merge(pHead2.next,pHead1)
    }
    return result;
}

5.复杂链表的赋值

这个对我来说完全没有理解,打算先把其他的链表做了。

6.两个链表的公共结点

function FindFirstCommonNode(pHead1, pHead2)
{
     var p1 = pHead1;
     var p2 = pHead2;
    while(p1!=p2){
        p1= (p1==null)?pHead2:p1.next
        p2= (p2==null)?pHead1:p2.next
    }
    return p1;
}

7.链表中环的入口结点

思路:定义两个节点,快结点一次走两步,慢节点一次走一步。如果两者相遇就说明有环,且两指针相遇的地方一定在环中,这时候再从该节点出发并且此时定义一个节点,这个节点初始值为头节点,头节点和慢节点相遇的位置一定是入口结点。
错误原因:每次用while的位置总是错用成if
是否重做:是
function EntryNodeOfLoop(pHead)
{
 var fast = pHead;
    var slow = pHead;
    while(fast!==null&&fast.next!==null){
        fast= fast.next.next;
        slow = slow.next
        if(fast==slow){
            var p = pHead;
            while(p!=slow){
                p=p.next;
                slow = slow.next;
            }
            return p;
        }
    }
    return null;
}