單鏈表倒置

既然是倒置,那我們一定是一定要走一遍單鏈表的,走單鏈表有兩種形式,遞歸和循環兩種方式,而遞歸正是壓棧和出棧,那麼我們就想起來了,這不就是順序和逆序的關係嗎?第二種就是循環,還記得我們曾今學習單鏈表的時候有一種插法叫做頭插法,這種插入複雜度爲O(1),不好的地方就是順序插入的數字,出來的時候卻是反的,所以這個不就是可以將原先的鏈表原地倒置過來嗎?

一:遞歸

  說到遞歸,我們腦子裏面一定要有一個V型圖,還有一個就是好記性不如爛筆頭,算法這東西很難用腦子想的清楚的,多畫畫圖就見青天了,下面我就舉個簡單的例子:現有鏈表L={8,1,6,3},需要將L倒置,然後我就畫好了V型圖。
這裏寫圖片描述

從圖中可以看到,當我遞歸到3再出棧的時候,只需要將6賦給3.next,1賦給6.next,然後這樣以此類推。。。最後結果就出來了,貌似口頭上描述起來很簡單,但是在寫代碼的時候需要注意以下幾個點,先上代碼說話。

          public LinkNode Reverse(LinkNode node)
          {
              if (node.next == null)
                  return node;

              var prevNode = Reverse(node.next);

              var temp = node.next;

             temp.next = node;

             node.next = null;

             return prevNode;
         }

第一點:我們在走鏈表的時候,可以操控的只有兩個結點,node和node.next,所以遞歸出口的時候,一定不能使用最常見的寫法。

       if (node == null)
            return node;

    而應該像下面這麼寫,其實就告訴我們只需要走到6節點就行了,用6.next來判斷下是不是鏈尾,這樣做是方便我們進行node和node.next進行節點交換。

             if (node.next == null)
                 return node;

第二點:當我們每一次出棧的時候,其實也是退到曾今壓棧時的方法環境中,進行節點交換的時候,也只能在當前的方法上下文中起效,比如說:出棧到1的時候,其實3和6的節點已經交換了,但是1這個方法環境不知道,它仍然指向6,但此時節點6.next再也不是3了,因爲曾今3和6進行了交換,所以這不是我們所期望的,所以在回退的時候,一定要有一個鏈表保存這個所有節點交換的集合,恰巧在鏈表中有一個特徵就是,只要我有一個指針始終指向頭結點的地址,它就相當於一個集合的功能了,因爲我不管你後面節點怎麼轉換,我都可以通過head.next依次找到後面痙攣的所有結點,比如下圖中在出棧的過程中,每個出棧的方法環境中都依次交換了node和node.next結點,而我的prevnode始終指向的是結點3,所以我通過3.next就可以找到後面所有的 變化,所以這裏就是prevnode的精妙之處。
這裏寫圖片描述

最後看一下倒置的輸出結果:

這裏寫圖片描述

二:非遞歸實現

  如果你知道頭插法,那麼循環實現真的很簡單,不像遞歸做法很難想到那個prevnode節點,我們知道頭插法是把新節點插入到鏈表的頭部,而我們遍歷的時候又可以控制兩個節點node和node.next,所以依次採用頭插法,將node.next插入到node之前,有人說,那插入到node節點之前不就亂了嗎?所以在操作之前,我可以把node.next先保存起來,比如放到申請的一個叫next的節點上,爲了保存新轉換的節點,我們再申請一個prev結點來保存頭插法中的新節點。

爲了好理解,畫圖如下,其實這裏要注意,結點還是那些結點,並沒有刪除再添加。
這裏寫圖片描述

          public LinkNode Reserve(LinkNode node)
          {
              LinkNode prev = null;
              LinkNode next = null;

              while (node != null)
              {
                  next = node.next;

                 node.next = prev;

                 prev = node;

                 node = next;
             }
             return prev;
         }

轉載自http://www.cnblogs.com/huangxincheng/p/4051854.html

發佈了20 篇原創文章 · 獲贊 37 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章