1. 程式人生 > >【數據結構】第三章學習小結

【數據結構】第三章學習小結

truct 如果 數值 tps 包括 https stack 判斷 .com

第三章知識小結

一.棧(特點是後進先出--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

目前學習中存在的問題:①不夠細心,對題目的理解能力還有所不足

②不能通過寫註釋來發現自己代碼中存在的問題

接下來的目標:周末認真復習,迎接下周的小測,繼續堅持打代碼

【數據結構】第三章學習小結