1. 程式人生 > >單鏈表的節點數,合並,相交,反轉

單鏈表的節點數,合並,相交,反轉

math 第一個 class reverse key 指針 系統 != 單鏈表相交

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

單鏈表的節點數,合並,相交,反轉