單鏈表的翻轉遞歸和非遞歸方式(php實現、)

早上好,最近在看但鏈表的翻轉,之前一直困惑,怎樣使用php實現,後來發現重要的是捋清單鏈表的數據結構和翻轉的基本原理,至於什麼語言實現,萬變不離其中,都是一樣的道理,接下來,介紹一下,php實現單鏈表的翻轉。

1、最重要的是理解單鏈表的數據結構,(鏈表操作一定要畫圖,畫圖才能理解的更爲深刻。)


1:單向鏈表:

單向鏈表的鏈表對象維護了一個 first 引用,該引用指向節點鏈表中的第一個節點對象,每個節點對象維護一個 next 引用,next引用指向下一個節點對象;(這裏注意:是引用指向的是節點對象:節點對象包含存儲的數據和next引用)

 2、我們知道迭代是從前往後依次處理,直到循環到鏈尾;而遞歸恰恰相反,首先一直迭代到鏈尾也就是遞歸基判斷的準則,然後再逐層返回處理到開頭。總結來說,鏈表翻轉操作的順序對於迭代來說是從鏈頭往鏈尾,而對於遞歸是從鏈尾往鏈頭。下面我會用詳細的圖文來剖析其中實現的細節

1)非遞歸方式(迭代)方式

迭代的方式是從鏈頭開始處理,如下圖給定一個存放5個數的鏈表


首先對於鏈表設置兩個指針:


    然後依次將舊鏈表上每一項添加在新鏈表的後面,然後新鏈表的頭指針NewH移向新的鏈表頭,如下圖所示。此處需要注意,不可以上來立即將上圖中P->next直接指向NewH,這樣存放2的地址就會被丟棄,後續鏈表保存的數據也隨之無法訪問。而是應該設置一個臨時指針tmp,先暫時指向P->next指向的地址空間,保存原鏈表後續數據。然後再讓P->next指向NewH,最後P=tmp就可以取回原鏈表的數據了,所有循環訪問也可以繼續展開下去。


 指針繼續向後移動,直到P指針指向NULL停止迭代。

最後一步:


2) 遞歸實現。

    我們再來看看遞歸實現鏈表翻轉的實現,前面非遞歸方式是從前面數1開始往後依次處理,而遞歸方式則恰恰相反,它先循環找到最後面指向的數5,然後從5開始處理依次翻轉整個鏈表。 
  首先指針H迭代到底如下圖所示,並且設置一個新的指針作爲翻轉後的鏈表的頭。由於整個鏈表翻轉之後的頭就是最後一個數,所以整個過程NewH指針一直指向存放5的地址空間。


    然後H指針逐層返回的時候依次做下圖的處理,將H指向的地址賦值給H->next->next指針,並且一定要記得讓H->next =NULL,也就是斷開現在指針的鏈接,否則新的鏈表形成了環,下一層H->next->next賦值的時候會覆蓋後續的值。


繼續返回操作:

上圖第一次如果沒有將存放4空間的next指針賦值指向NULL,第二次H->next->next=H,就會將存放5的地址空間覆蓋爲3,這樣鏈表一切都大亂了。接着逐層返回下去,直到對存放1的地址空間處理。

返回到頭:


三、以下是具體的代碼實現

<?php
class Node{
    public   $next=null;
    public $data;
    public function __construct($data=''){
        $this->data=$data;
        
    }


}

//新增
 function addNode($head,$data){
        
        $cur=$head;
        while($cur->next!=null){
            $cur=$cur->next;
        }
        $node=new Node($data);
        $cur->next=$node;
        
    }
    
    //遍歷
    function showNode($head){
        $cur=$head;
        while($cur->next!=null){
            $cur=$cur->next;
            echo $cur->data.PHP_EOL;
        }
        
    }
    //feidigui非遞歸 
    function reversNode($head){
        if($head==null){
            return false;
        }
        $new=null;
        $cur=$head;
        while($cur!=null){
            $temp=$cur->next;
            $cur->next=$new;
            $new=$cur;
            $cur=$temp;
            
        }
        
        return $new;
        
    }
    //遞歸方式實現
    function reversRecursionNode($head){
        if($head->next==null){
            return $head ;
        }
         $phead=reversRecursionNode($head->next);
         $head->next->next=$head;
        $head->next=null;
         return $phead;
        


        
    }
    
    function test(){
        $head=new Node();
        addNode($head,'A');
        addNode($head,'B');
        addNode($head,'C');
        addNode($head,'D');
        showNode($head);
        echo '--------------';
        //$new=reversNode($head);
        $new=reversRecursionNode($head);
        echo'-----------------';
        showNode($new);
        echo'------------------------';
        $head=new Node();
        $head->next=$new;
        showNode($head);
    }
    
    test();

?>


搬磚不容易,喜歡就賞點。

                                                                      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章