劍指Offer(java版):在O(1)時間刪除鏈表節點

題目:給定單向鏈表的頭指針和一個節點指針,定義一個函數在O(1)時間刪除該節點。安全

在單向鏈表中刪除一個節點,最常規的方法無疑是從鏈表的頭結點開始,順序遍歷查找要刪除的節點,並在鏈表中刪除該節點。函數

好比圖a所表示的鏈表中,咱們要刪除節點i,能夠從鏈表的頭節點a開 始順序遍歷,發現節點h的m_PNext指向要刪除的節點i,因而咱們可疑把節點h的m_PNext指向i的下一個節點即爲j。指針調整以後,咱們就能夠 安全地刪除節點i並保證鏈表沒有斷開。這種思路因爲須要順序查找,時間複雜度天然就是O(n)了。指針

之因此要從頭開始查找,是由於咱們須要獲得被刪除的節點的前面一個節點。在單向鏈表中,節點中沒有前一個節點的指針,因此只好從鏈表的頭結點開始順序查找。路由

那是否是必定要獲得被刪除的節點的前一個節點呢?答案是否認的。咱們可疑很方面地獲得要刪除的節點的下一個節點。若是咱們把下一個節點的內容複製到要刪除的節點上覆蓋原有的內容,再把下一個節點刪除,那是否是就至關於把當前要刪除的節點刪除了?class

咱們仍是之前面的例子來分析這種思路,咱們要刪除的節點i,先把i的下一個節點j的內容複製到i,而後把i的指針指向節點j的下一個節點。此時再刪除節點j,其效果恰好是把節點i給刪除了(圖c)List

上述問題還有一個問題;若是要刪除的節點位於鏈表的尾部,那麼它就沒有下一個節點,怎麼辦?咱們讓然從鏈表的頭節點開始,順序遍歷獲得該節點的前序節點,並完成刪除操做。遍歷

最後須要注意的是,若是鏈表中只有一個節點,而咱們又要 鏈表的頭節點(也是尾節點),此時咱們在刪除節點以後,還須要把鏈表的頭節點設置爲NULL。方法

有了這種思路,如今咱們是實現代碼:im

package cglib;鏈表

class ListNode
{ int data;
  ListNode nextNode;
}
public class DeleteNode {
    public static void main(String[] args) {
        ListNode head=new ListNode();
        ListNode second=new ListNode();
        ListNode third=new ListNode();
        head.nextNode=second;
        second.nextNode=third;
        head.data=1;
        second.data=2;
        third.data=3;
        DeleteNode p13=new DeleteNode();
        p13.deleteNode(head, second);
        
        System.out.println(head.nextNode.data);
        }
        public void deleteNode(ListNode head,ListNode deListNode){
        if(deListNode==null||head==null){
        return;
        }
        if(head==deListNode){//只有一個結點,刪除頭結點
        head=null;
        }
        else{
        if(deListNode.nextNode==null){//刪除尾結點,順序遍歷獲得前一個結點
        ListNode pointListNode=head;//從頭結點開始
        while(pointListNode.nextNode.nextNode!=null){
        pointListNode=pointListNode.nextNode;
        }
        pointListNode.nextNode=null;
        }
        else{ //刪除的不是尾結點
        deListNode.data=deListNode.nextNode.data;//複製
        deListNode.nextNode=deListNode.nextNode.nextNode;
        }
        }
        }
}


輸出:

3

相關文章
相關標籤/搜索