單鏈表的節點數,合並,相交,反轉
阿新 • • 發佈:2017-05-22
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
單鏈表的節點數,合並,相交,反轉