程式猿必修課之資料結構(七)棧2

2021-08-23 12:13:36 字數 2557 閱讀 2289

斐波那契(fibonacci)是乙個經典的遞迴例子。

數字 1,1,2,3,5,8,13......構成乙個序列,它的特點是:前面相鄰兩項之和是後一項的值。用數學函式來定義是:

斐波那契數列

用遞迴實現列印出前 40 位的斐波那契數列數的**如下:

# includeint fbi(int);

int main()

return 0;

}int fbi(int i)

函式呼叫自己,可以理解為呼叫另乙個函式,只不過,這個函式和自己一樣而已。

乙個直接或通過一系列的呼叫語句間接的呼叫自己的函式,稱為遞迴函式。

每個遞迴定義必須至少有乙個條件滿足時遞迴不再進行,即不再呼叫自己而是返回值並退出。

迭代使用的是迴圈結構,遞迴使用的是選擇結構。遞迴能使程式的結構更清晰、更簡潔、更容易理解,但是大量的遞迴呼叫會耗費大量的時間和記憶體。迭代則不需要反覆呼叫函式和占用額外的記憶體。所以,凡事都有利有弊,我們應該視情況選擇合適的方式。

對於"9 + (3 -1)x 3 + 10 ÷ 2" ,如果要用字尾表示法應該是"9 3 1 - 3 * + 1 0 2 / +",這樣的表示式稱為字尾表示式,叫字尾的原因在於所有的符號都是在要運算數字的後面出現。

我們把平時所用的標準四則運算表示式 ,即 9 + ( 3-1 ) x 3 + 10 ÷ 2 叫做中綴表示式,因為所有的運算符號都在兩數字的中間。那麼如何將中綴表示式轉換為字尾表示式呢?

中綴表示式轉字尾表示式的規則是:

從左到右遍歷中綴表示式的每個數字和符號,若是數字就輸出;若是符號,就判斷其與棧頂符號的優先順序,如果是右括號或者優先順序低於棧頂符號,則棧頂元素依次出棧並輸出,再將當前符號進棧......直到最終輸出字尾表示式為止。

按照上面的規則,把 9 + ( 3 - 1 ) x 3 + 10 ÷ 2 轉換為字尾表示式

用 temp 表示當前輸出過的所有內容,用 stack 表示儲存運算子的棧。

第乙個字元是數字 9,temp = "9";後面是符號「+」進棧,stack = "+";

第三個字元是「(」,因為它是左括號,所以進棧,stack = "+ (";

第四個字元是數字 3,所以 temp = "9 3";後面是符號「-」進棧,stack = 「+ ( -」;

第六個字元是數字 1,所以 temp = "9 3 1";後面是「)」,所以我們要把 stack 中的棧頂符號出棧,直到「(」出棧為止。因為「(」上面只有乙個「-」,所以輸出「-」,temp = 「9 3 1 -」,stack = "+";

第八個字元是「x」,此時棧頂符號為「+」,優先順序比「x」低,所以「x」進棧,stack = 「+ *」;

第九個字元是數字 3,所以 temp = 「9 3 1 - 3";

第十個字元是「+」,此時棧頂元素為「 * 」比「+」的優先順序高,所以棧頂元素出棧並輸出(沒有比「+」更低的優先順序,所以全部出棧)然後再將「+」入棧,temp = "9 3 1 - 3 * +",stack = "+";

第十乙個字元是數字10,temp = "9 3 1 - 3 * + 10",後面是符號「÷」,所以「/"入棧,stack = "+ /";

最後乙個字元是數字2,temp = "9 3 1 - 3 * + 10 2";

因為已經到了最後,所以將棧中符號全部出棧並輸出,temp = "9 3 1 - 3 * + 10 2 / +"; stack 為空棧,結束。

所以 9 + ( 3 - 1 ) x 3 + 10 ÷ 2 轉換為字尾表示式結果為 temp 的值"9 3 1 - 3 * + 10 2 / +"。

規則:從左到右遍歷表示式的每個數字和符號,遇到數字就進棧,遇到符號就將處於棧頂的兩個數字出棧進行運算;再將運算結果進棧,直到遍歷結束。

求字尾表示式 "9 3 1 - 3 * + 10 2 / +"的值:

用 stack 表示儲存符號的棧。

因為字尾表示式的前 3 個字元都是數字,所以「9 3 1」依次進棧,stack = 「9 3 1」;

接下來是「-」,所以將棧頂的「1」出棧作為「減數」,再將「3」出棧作為「被減數」,計算 3 - 1 = 2,再將 2 進棧,stack = 「9 2」;

接著是數字 3 進棧,stack = 「9 2 3」;

再接著是「*」,所以將棧頂的「3」出棧,再將「2」出棧,2 * 3 = 6;將 6 進棧,stack = 「9 6」;

後面是「+」,將棧中6 和 9 出棧並相加得到 15,將15進棧,stack = 「15」;

接著是數字10 和 2,將它們依次進棧,stack = 「15 10 2」;

後面是「/」,將 2 出棧作為除數,再將 10 出棧作為被除數,10 / 2 = 5,將 5 進棧,stack = "15 5";

最後乙個符號是「+」,所以將 15 與 5 相加得到 20,再將 20 入棧,stack = 「20」;

此時,已經沒有符號了,所以將棧中的 20 出棧,運算結果為 20。

將中綴表示式轉為字尾表示式,棧用來儲存運算符號。

計算字尾表示式的結果,棧用來儲存運算的數字。

程式猿必修課之資料結構(十)樹1

樹是一對多的資料結構 樹 tree 是 n n 0 個結點的有限集。n 0 時,稱為空樹。在任意一棵非空樹中 其實樹的定義用到了遞迴的方法。樹的每乙個結點包含乙個資料元素和若干個指向其子樹的分支。結點的度 結點擁有的子樹的個數稱為結點的度 degree 度為 0 的結點稱為葉結點 leaf 或終端結...

程式猿必修課之資料結構(八)佇列

佇列 queue 是只允許在一端進行插入操作,而在另一端進行刪除操作的線性表。佇列是一種先進先出 first in first out 的線性表,簡稱fifo。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。佇列是特殊的線性表,因此它的各種操作類似線性表,不同的是插入資料只能在隊尾進行,刪除資料只能...

程式猿必修課之資料結構(一)資料結構基本概念和術語

資料結構 是相互之間存在一種或多種特定關係的資料元素的集合。本文將 資料結構 分為 資料 和 結構 兩部分。程式設計 資料結構 演算法 資料 資料 是描述客觀事物的符號,是計算機中可以操作的物件,是能被計算機識別,並輸入給計算機處理的符號集合。也就是說,我們這裡說的資料其實就是符號,而且這些符號必須...