【數據結構】第三章學習小結
第三章知識小結
一.棧(特點是後進先出--LIFO)
1.抽象數據類型(ADT)
ADT:stack
InitStack(Stack &S);
Push(Stack &S);
Pop(Stack &S);
2.按照存儲結構可分為:順序棧,鏈棧
順序棧的類型定義:
const int MAXSIZE =100;
typedef int ElemType;/*類型視情況而定,這裏定義為int */
typedef struct
{
ElemType data[MAXSIZE];
int top;/*棧頂標誌*/
int stacksize;/*棧的最大容量*/
}Sqstack;
鏈棧的類型定義:
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}StackNode,*LinkStack;
棧與遞歸
遞歸:一個對象部分地包含它自己,換句話說,就是自己給自己定義。
每次遞歸都會保存的信息:1.返回地址2.參數值3.引用的局部變量
遞歸優缺點分析:
優點:結構清晰,程序易讀
缺點:每次調用要生成工作記錄,保存狀態信息入棧,返回時要出棧,恢復狀態信息,時間開銷大
解決遞歸問題可以用分治法:
void p(參數表)
{
if(遞歸結束條件成立) 的解/*遞歸終止條件*/
else p(較小的參數);/*遞歸步驟*/
二.隊列(先進先出-FIFO,只允許在表的一端進行插入,而在另一端刪除元素)
由於順序隊用的比較少,這裏主要說說鏈棧
鏈隊的類型定義:
typedef struct node{
ElemType data;
struct node *next;
}LNode;/*結點*/
typedef struct{
LNode *front;/*頭指針*/
LNode *rear;/*尾指針*/
}LinkQueue;
在第三章裏,我學到了兩種重要的線性結構---棧和隊列,兩者都有順序結構和鏈式結構的表達方式,相較於順序結構,我更青睞於使用鏈棧和鏈隊,因為順序棧和順序表一樣,會受到最大空間容量的限制,要想擴大容量,需要的工作量是非常大的,我在上一章內容就學到了,鏈式結構在進行插入與刪除操作時,能省去很大一部分不必要的操作。對於鏈棧來說,沒有必要設置頭結點,直接將棧頂置空就行。入棧時直接為入棧的元素分配空間,不需要判斷棧滿。出棧時需要釋放出棧元素的棧頂空間。(嘗試過不加這一操作,好像對程序影響不大)
對於鏈隊,我一般都會構造一個帶有頭結點的空隊,並將隊尾指針的隊頭指針都指向該頭結點,入隊的時候只需為入隊的元素分配結點空間,並設置一個指針p指向該結點,將隊尾指針修改為p,鏈隊在出隊時需要特別註意的是,當隊列最後一個元素被刪除時,隊列尾指針會丟失,這時候需要對隊尾指針重新賦值,即將隊尾指針指向頭結點
完成作業時遇到的困難:
1.在做pta上的實踐題時,花了好幾天時間DeBug,將一些自己因為粗心打漏幾個字符造成的問題解決後,自己在Dev上測試也沒問題,就想這一次在pta提交總該會一次過吧。沒想到,前三個測試點都過得了,就是在最後一個最大N的時候掛掉了。
解決方法:嘗試通過寫註釋和在關鍵變量後面設置輸出語句,可惜未果。終於,在一次和同學分享自己的思路時,發現了一處疑點,原題目並沒有要求將客戶編號排好序,只是題目中給的樣例讓我產生了錯覺,非得加一個排序函數。將排序函數刪掉後在提交一次,竟然過了!(好幾天的瘋狂找Bug,竟是因為這小小的細節,果然是細節決定成敗)
刻苦銘心的教訓:一定要先看清楚題目再做題呀!
2.在做到括號匹配這個問題時,一開始我是參考了書上的例題的代碼,定義了一個char型變量來存儲字符串,但是這種方法每次只能讀入一個字符。
之後在調試的過程中,我又遇到了系統報錯,內容是swich語句裏的參數必須是一個整型變量。
解決方法:1.果斷拋棄只用一個CHAR型變量的方法,改用字符數組(之後可以循環讀取數組裏的字符)
2.將輸入的字符統一轉化為ASCII碼(即為整型變量)
void Match()/*判斷輸入的一段字符串中所包括的符號是否匹配,如果匹配,輸出"yes", 否則輸出"no"*/ { int length; LinkStack S; InitStack( S);/*初始化空棧*/ char ch[MAXSIZE]; cin.getline(ch,MAXSIZE); length=strlen(ch);/*獲得輸入字符串的長度*/ int flag=1;/*標記匹配結果並返回結果*/ for(int i=0;i<length;i++) { int temp;/*將字符轉化為ASCII碼*/ temp=(int)ch[i]; switch(temp) { case 91:/*"["的ASCII碼*/ case 40:/*"("的ASCII碼*/ case 123:/*"{"的ASCII碼*/ Push(S,temp);/*若是左括號,入棧*/ break; case 93 : if(!StackEmpty(S)&&GetTop(S)==91) Pop(S);/*若棧非空且符號匹配,則棧頂出棧*/ else flag=0;/*反之,返回0*/ break; case 41: if(!StackEmpty(S)&&GetTop(S)==40) Pop(S); else flag=0; break; case 125: if(!StackEmpty(S)&&GetTop(S)==123) Pop(S); else flag=0; break; } }
參考資料:https://www.cnblogs.com/Draymonder/p/6944479.html
https://blog.csdn.net/qq_39091609/article/details/76618628
目前學習中存在的問題:①不夠細心,對題目的理解能力還有所不足
②不能通過寫註釋來發現自己代碼中存在的問題
接下來的目標:周末認真復習,迎接下周的小測,繼續堅持打代碼
【數據結構】第三章學習小結