1. 程式人生 > 其它 >演算法之遞迴(2)- 連結串列遍歷

演算法之遞迴(2)- 連結串列遍歷

(3條訊息) 演算法之遞迴(2)- 連結串列遍歷_weixin_30951231的部落格-CSDN部落格
https://blog.csdn.net/weixin_30951231/article/details/99482611

在遞迴(1)中,簡單的介紹了遞迴的思想,並且通過一個例子簡單闡述了遞迴是如何工作的,並且遞迴的實現是以線性結構來表示的。之所以用線性的,是因為其易於理解;如果使用樹結構,將加大對問題的難度,不利於初學者理解遞迴的思想。

為什麼用遞迴

關於為什麼用遞迴,我個人的理解是遞迴不要違背演算法的初衷,即期待傳入xxx值,加工後返回xxx值。不要為了遞迴而遞迴,容易造成對函式語義的奇異。另外,通過遞迴,可以讓程式碼更加整潔,短小,精湛,優美。當然,還會存在一定程度的效能損耗;不過,合理的使用,對於那部分的損耗可以忽略不計。

讓我們以單鏈表為例,理解一下遞迴是如何工作的。

1.遍歷單鏈表

迴圈

遞迴

 private void TraveserL(LNode head)
 {
     if (head == null)
         return;

     while (head != null)
     {
         Console.WriteLine(p.data);
         p = p.next;
     }
 }


private void TraveserR(LNode head) { if (head == null) return; Console.WriteLine(head.data); TraveserR(head.next); }



對於迴圈遍歷我想不用多說了吧。不過,值得注意的是遞迴的遍歷,先對資料進行列印,然後遍歷下一個節點。有趣的是,如果將列印語句放在遞迴呼叫的後面,將是一個逆序的列印。

分析

假設連結串列的結構是這樣的

A->B->C->D->E->F

遞迴呼叫時將發生如下情形

1.在遞迴呼叫之前列印(意味著進入函式體的時候列印)

(1)進入函式(從左到右讀)

A->

B->

C->

D->

E->

F->

列印A

列印B

列印C

列印D

列印E

列印F

輸出:A, B, C, D, E, F.

(2)當函式退出(從右到左度)

<-A

<-B

<-C

<-D

<-E

<-F

2.在遞迴呼叫之後(意味著只有退出函式體的時候,才進行列印)

(1)進入函式體(從左到右讀)

A->

B->

C->

D->

E->

F->

(2)退出出函式體(從右到左讀)

<-A

<-B

<-C

<-D

<-E

<-F

列印A

列印B

列印C

列印D

列印E

列印F

輸出:F, E, D, C, B, A

結論,當操作在遞迴呼叫之後進行,那麼是從後向前對連結串列執行操作。這也是棧的特性之一。當然,具體何時決定,取決與程式設計師自己,是想從頭開始順序操作,還是後到前逆序操作,具體問題具體分析。

轉載於:https://www.cnblogs.com/lucasluo/archive/2012/07/30/2615902.html