1.基礎知識(了解棧結構)
先回顧一下關於棧的最簡單知識;
本文主要涉及線性棧
假如我們不考慮棧底,棧底是固定不動的,只考慮棧頂,那么棧就像一只放在桌子上的空杯,杯底固定貼在桌子上。
而如果我們往這個杯子里放方糖,先放進去的方糖總是被后放進去的方糖壓在下面,也就是說要先取出后放進去的方糖才能取出先放進去的方糖。
這就是棧所謂的 “先進后出” 特性。
再想象一下,我們把手指壓在最后放進去的方糖上面,每次取出方糖的時候用手指把方糖剔出去,之后壓在下一塊方糖上 。這根手指就像一個標志,標志着我們當前能剔出哪塊方糖。
杯子上面還能有刻度,而且每兩個刻度條之間的距離正好是一塊方糖的高度。
現在把水杯,方糖和手指都抽象一下。把手指抽象成一根指向杯頂(棧頂)的指針,把方糖抽象成我們要放進去的元素(element), 把水杯抽象成一個U字型的邊框,來約束我們的長方形方糖只能向上堆疊。
以下的內容都會以此數據結構作為基礎,講解遞歸和棧的聯系
可能你寫過某道題目,說要用棧來實現某某功能,不能用遞歸。但實際上,遞歸用到的數據結構本質上就是棧。所以說,遞歸只是在你看不到的地方用了棧,完成了你的操作。
為什么那么說呢?
我們來淺淺地了解一下在內存中函數調用的過程。
眾所周知,內存是的抽象模型是一串線性的單元格。
在函數調用過程中,每個函數的開始,都會在內存中一段被稱為棧區的空間內創建棧幀(稍后解釋)
這片棧區 就好像我們上面說的水杯,而棧幀就是上面所說的方糖
內存被編址成一個個存儲單元,上面所說的兩個刻度條間的空間就可以當成一個存儲單元,並且每個存儲單元對應一個唯一的數字(地址)
但實際上,函數調用過程中,在內存中是用兩根指針確定一個元素的,就像杯子里裝了沙,你用食指和大拇指那么一捏,表示這是一個方糖高的沙。
下一篇 :
棧論 : 遞歸與棧式訪問,如何用棧實現所有遞歸操作(函數調用底層篇)
護眼綠:
沒人看的結語:
首先很感謝你看到這里,辛苦了。
文章中某些地方可能不正確或不准確,代碼也可能不夠高效可讀,希望讀者能夠幫忙指正,共同學習進步。