單鏈表的遞迴與非遞迴實現

2022-02-03 09:33:07 字數 2077 閱讀 5771

一:遞迴版本

1 class linklist

2

9 10 private linknode head;

11 12 public void add(int data)

13 ;

17 }

18 else

19

22 }

23 24 public void add(linknode node, int data)

25 ;

29 return;

30 }

31 32 add(node.next, data);

33 }

34 }

二:非遞迴版本

1    class linklist

2

9 10 private linknode head;

11 12 public void add(int data)

13 ;

15 16 if (head == null)

17

20 else

21

28 29 temp.next = node;

30 }

31 }

32 }

這個非遞迴不理解的地方在於臨時變數temp,提出的問題就是為什麼:「temp.next=node」 之後,head的值發生了改變?我想之所以不能理解,絕逼是對

引用型別的記憶體分配不了解,而這個非遞迴版本恰恰就是用引用型別這個記憶體分配技巧來實現 」非遞迴構建單鏈表「。。。為了不讓別人踩上這個坑,我還是大

概說一下流程,大概是這樣的,當我們在new乙個引用型別的時候,clr就要計算例項欄位和所有基類上的例項欄位的大小,然後再在堆上分配合理的記憶體塊,

最後把堆上的記憶體塊的首位址儲存在棧上面。

為了方便理解,現在假如linklist裡面有三個結點:instance1 -> instance2 -> instance3, 

第一句:

1 linknode temp = head;
這個句子不難理解吧,把head的位址賦給temp,那麼棧上temp的位址也就是head的位址,head的位址就是指向instacnce1記憶體塊位址。

了temp,然後就發現instance3的next為null,然後就跳出迴圈。

第三句:從上一句可以看到,instance3的next已經為null了,這時候就把新構建的結點:linknode node = new linknode() ;賦

給temp的next指標上來繼續構建鍊錶。

可以看到這時候instance4就構造到了instance3之後,同時temp.next已經是儲存instance4的記憶體位址,這一些操作對head來說都是透明的,它也不管

後面怎麼操作,當你遍歷head的時候會驚奇的發現居然我的鍊錶中多了乙個instance4,這個也就是朋友疑惑的地方,如果看到這個記憶體分配圖的話,

也許會豁然開朗,當然這篇博文沒什麼技術含量,也是自己一時有感而發。

單鏈表反轉 非遞迴 遞迴方式實現

鍊錶的翻轉是程式設計師面試中出現頻度最高的問題之一,常見的解決方法分為遞迴和迭代兩種。最近在複習的時候,發現網上的資料都只告訴了怎麼做,但是根本沒有好好介紹兩種方法的實現過程與原理。所以我覺得有必要好好的整理一篇博文,來幫忙大家一步步理解其中的實現細節。我們知道迭代是從前往後依次處理,直到迴圈到鏈尾...

單鏈表的逆序實現,遞迴和非遞迴演算法

這個也是很常見的面試題目。剛開始見過,開了一下別人寫的以為理解了,讓我自己寫,我才發現原來裡面的細節是很多的,可以說,你也許大概懂演算法在幹什麼,可是,你若如果不注意細節,根本體會不到演算法裡面的每一行的意思,今天就是看了別人乙個演算法,被誤導了,怎麼都沒理解他的意思。結果看了10幾篇,果然他裡面漏...

單鏈表反轉遞迴與非遞迴演算法

1.如下 1 include 2 include 3 4using namespace std 56 struct node 715 16 17 node createlist int elem,int length 1825 return p 26 27 28void destroylist no...