首先是寫棧的習慣:一定要在建立完棧後 就立即寫上銷毀棧的函式 否則很容易遺忘銷毀 導致記憶體洩露
在唐老師講的符號配對檢測的程式時 有乙個小細節 老師並沒有提出來 但是後來發現了 :
char* c = (char*)linkstack_pop(stack);
//進行檢測 格外注意 一定要先c==null
if( (c == null) || !match(*c,code[i]) )
這裡進行了標紅 就是先從堆疊裡取出了棧頂元素 然後進行判斷 這裡先進性了判斷c是否是null ,因為如果要是先呼叫match函式 當*c 的時候 可能會由於c的指向位址是null
所以導致不發找到該位址 最終導致程式崩潰;
然後是計算器的執行:人類習慣的表示式是中綴表示式例如: 3+5、3+4+4、3*(3+3)*4;
而機器習慣的運算表示式是:35+,34+4+;等等
以下是唐老師給出的例子:
中綴表示式:字尾表示式:
5 + 3 =5 3 +
1 + 2 * 3 = 1 2 3 * +
9 + ( 3 – 1 ) * 5= 9 3 1 – 5 * +
而如何將人們習慣的中綴表示式轉成字尾表示式呢??這個老師給出了答案:
遍歷中綴表示式中的數字和符號
對於數字:直接輸出 直接輸出
對於符號:
• 左括號 :進棧 進棧
• 符號 :與棧頂符號進行優先順序比較 與棧頂符號進行優先順序比較
•棧頂符號優先順序低:進棧 進棧
•棧頂符號優先順序不低:將棧頂符號彈出並輸出 將棧頂符號彈出並輸出, ,之後進棧 之後進棧
•右括號:將棧頂符號彈出並輸出 將棧頂符號彈出並輸出, ,直到匹配左括號 直到匹配左括號
遍歷結束:將棧中的所有符號彈出並輸出 將棧中的所有符號彈出並輸出
而計算機又是如何對字尾表示式進行運算的呢??這個老師也給出了答案:
遍歷字尾表示式中的數字和符號
對於數字:進棧 進棧
對於符號:
•從棧中彈出右運算元(記住先彈出的是有運算元)
•從棧中彈出左運算元(後彈出的是左運算元)
• 根據符號進行運算
• 將運算結果壓入棧中
遍歷結束:棧中的唯一數字為計算結果
對於順序鍊錶唐老師用的是鍊錶的尾作為棧頂,而普通的鍊錶做棧是用的是表頭作為棧頂;
我覺得對於順序煉表表尾作為棧頂很正確,畢竟順序鍊錶是陣列,如果以表頭作為棧頂,在進行插入的時候,要將所有資料都進行後移,這樣過於浪費執行時間
而用普通的鍊錶作為棧時,用表頭或者標尾作為棧頂就沒有什麼區別,用表頭作為棧頂是,不論是取元素還是刪除元素時,直接將函式中需要操作的節點位置寫零即可,而標尾還要檢測長度;
對於第四專題四的課後習題裡唐老師讓將整個計算器的演算法不全,可以識別兩位數還有能夠自己進行中綴轉字尾,然後進行字尾計算;
這裡就需要設定兩個棧了:1:符號棧 2:數字棧
當為數字是,直接進入數字棧,而為符號時,就進入符號棧
而進入符號棧時,什麼情況入棧,什麼情況出棧和中綴轉字尾的方法一樣,當符號要進行出棧時,數字棧就要同時進行左右操作時出棧,然後進行運算,再將結果數字棧中;
這樣就可以實現中綴轉字尾,字尾進行計算了;
但這裡有乙個小細節就是當數字入棧是一定要先把字元的數字轉成數字int型 然後在進行壓棧,否則如果在後面的計算結果進行壓棧時,如果結果是兩位數,然麼用字元表示就會出錯,然後也沒法將兩位數轉成數字(因為不確定生成的是幾位數)所以最好的方法就是在數字壓棧時就直接轉成int型的數字然後壓棧,就不會涉及到結果是幾位數了;
//判斷是否是數字
int isnumber(char c)
//輸出字元函式
void output(char c)
//判斷是否是左括號
int isleft(char c)
//判斷是否是右括號
int isright(char c)
//判斷是否是操作符
int isoperator(char c)
//判斷操作符的優先順序
int priority(char c)
if( (c == '*') || (c == '/') )
return ret;
}
//字元轉成數字
int value( char c )
int express(int left, int right, char op)
return ret;
}
//轉字尾與字尾計算結合體
int arithmic(const char* exp)
if( linkstack_size(num) > 1)
ret = (int)linkstack_pop(num);
}//一定要記得銷毀棧
linkstack_destroy(num);
linkstack_destroy(ope);
return ret;
}
唐老師 資料結構 專題五
這個專題講的內容是遞迴,並且這節的 量都不是很大,關鍵就是遞迴的思想,對於可以用遞迴去完成的任務,應該運用整體的思想,不用把每一步都想得很清楚,並且一定要有最後的結束判斷 對 還有個重要內容就是唐老師講到了計算機在函式與函式呼叫的時候,要利用棧,而這個棧是類似於我們之前用到的順序棧,就是一開始就已經...
唐老師資料結構專題八2
前面已經說到,二叉樹使用及其廣泛,現在就來說一下 在這裡先進行宣告 這裡所有樹的結點完全沒有指向父親結點的指標,唐老師沒有指名原因,但是他後面的一句話,感覺應該是他的原因,那就是做出二叉樹,也是為了節省空間,所以就沒有在樹節點裡包含指向父親結點的指標。首先是二叉樹的定義 二叉樹是由 n 個結點組成的...
唐老師資料結構專題八3
關於二叉樹的建立 這裡有個問題,就是二叉樹,就不能想1中講的那樣,建立兩個鍊錶,乙個孩子鍊錶,乙個組織鍊錶,因為二叉樹的孩子是分左右的,這個順序不能搞混,所以就直接是在每個二叉樹的結點中設定兩個指標,分別指向左右孩子,這樣就可以了,但是又有乙個問題隨之而來,那就是如何定位?這個問題唐老師給了乙個很形...