三、棧和隊列 | 數據結構

三、棧和隊列 | 數據結構

來自專欄 輕鬆跨考計算機專業研究生入學考試

一、棧和隊列的基本概念

1、棧的基本概念

棧的定義:一種只能在一端進行插入和刪除操作的線性表。可以進行操作的一端叫做棧頂,另一端叫做棧底。棧的刪除和插入操作一般叫做進棧和出棧。

2、棧的特點

先進後出(FILO)

3、棧的存儲結構

一般有兩種:鏈式棧和順序棧。可以理解成在操作上加以限制的鏈表和順序表。

4、棧的數學性質:Catalan數

N=frac{1}{n+1}C_{2n}^{n}

二、棧和隊列的存儲結構、演算法和應用

1、棧和隊列結構體定義

1)順序棧

typedef struct { int data[maxSize]; int top;}Sqstack;

2)鏈棧結點定義

typedef struct LNode{ int data; struct LNode*next;}LNode;

3)順序隊列定義

typedef struct { int data[maxSize]; int front; int rear;}SqQueue;

4)鏈隊定義

a、鏈隊結點

typedef struct QNode{ int data; struct QNode*next;}QNode;

b、鏈隊類型

typedef struct{ QNode*front; QNode*rear;}LiQueue;

2、順序棧

1)順序棧的幾個要素

a、幾個狀態:

I、棧為空:st.top==-1(從0開始存儲)

II、棧為滿:st.top==maxSize-1

III、上溢:棧滿時繼續入棧就會發生上溢的狀態。

IV、下溢:棧空時繼續出棧就會發生下溢的狀態。

b、兩個操作

I、進棧:st.data[++st.top]=x;

II、出棧:x=st.data[st.top---];

2)初始化棧的代碼

void initStack(Sqstack& st){ st.top=-1;}

3)判斷棧空的代碼

int isEmpty(Sqstack& st){ if(st.top==-1)return 1; else return 0;}

4)進棧代碼

int push(Sqstack& st,int x){ if(-1==st.top)return 0; st.data[++st.top]=x; return 1;}

5)出棧代碼

int pop(Sqstack& st,int &x){ if(-1==st.top)return 0; x=st.data[st.top--]; return 1;}

3、棧鏈

1)鏈棧的定義

a、兩個狀態

I、棧空:lst->next==NULL;

II、棧滿:不存在棧滿的情況(假設內存無限大的情況)

2)鏈棧的初始化

void initStack(LNode* &lst){ lst=(LNode*)malloc(sizeof(LNode));//創造一個頭結點 lst->next=NULL;}

3)判斷棧為空

int isEmpty(LNode* lst){ if(NULL==lst->next)return 1; else return 0;}

4)進棧代碼

void push(LNode* &lst,int x){ LNode* p=(LNode*)malloc(sizeof(LNode)); p->data=x; p->next=NULL;//將新節點指針域置NULL,可以避免一些錯誤 p->next=lst->next; lst->next=p;}

5)出棧代碼

int pop(LNode* &lst,int &x){//出棧數據保存於x if(NULL==lst->next)return 0; LNode*p=lst->next; lst->next=lst->next->next; x=p->data; free(p); return 1;}

4、棧的應用

1)括弧匹配Valid Parentheses - LeetCode

2)求逆波蘭表達式POJ 2694:逆波蘭表達式

5、順序隊

1)循環隊列

隊列的front指針指向剛出隊的元素,rear指針指向剛入隊的元素。隊列進隊時rear+=1,出隊時,front+=1,兩個指針最終會到達maxSize-1處,雖然隊中已經沒有元素,但無法讓元素進隊,這就是假溢出。

為了解決這個問題,可以將隊列的尾部和頭部連接起來,弄成一個環,如圖。

2)循環隊列要素

a、兩個狀態

I、隊空:qu.rear==qu.front

II、隊滿:(qu.rear+1)%maxSize==qu.front

b、兩個操作

I、進隊:qu.rear=(qu.rear+1)%maxSize; qu.data[qu.rear]=x;

II、出隊:qu.front=(qu.front+1)%maxSize;x=qu.data[qu.front];

3)初始化隊列

void initQueue(SqQueue &qu){ qu.front=qu.rear;}

4)判斷隊列是否為空

int isEmpty(SqQueue &qu){ if(qu.front==qu.rear)return 1; else return 0;}

5)進隊

int enQueue(SqQueue &qu,int x){ if(qu.front==qu.rear)return 0; qu.rear=(qu.rear+1)%maxSize; qu.data[qu.rear]=x; return 1;}

6)出隊

int deQueue(SqQueue &qu,int &x){ if(qu.front==qu.rear)return 0; qu.front=(qu.front+1)%maxSize; x=qu.data[qu.front]; return 1;}

6、鏈隊

1)鏈隊的要素

a、兩個狀態:

I、隊為空:lqu->front==NULL||lqu->rear==NULL

II、隊為滿:不存在隊滿(假設內存無限)

b、兩個操作

I、p進隊:lqu->rear->next=p;lqu->rear=p;

II、出隊為x:p=lqu->front;x=p->data;lqu->front=lqu->front->next;

2)初始化鏈表

void initQueue(LiQueue* &lqu){ lqu=(LiQueue*)malloc(sizeof(LiQueue)); lqu->front=lqu->rear=NULL;}

3)判斷隊空

int isEmpty(LiQueue* lqu){ if(!lqu->front||!lqu->rear)return 1; else return 0;}

4)入隊

void enQueue(LiQueue* lqu,int x){ QNode*p=(QNode*)malloc(sizeof(QNode)); p->data=x; p->next=NULL; if(!lqu->front||!lqu->rear) lqu->front=lqu->rear=p; else{ lqu->rear->next=p; lqu->rear=p; }}

5)出隊

int deQueue(LiQueue* lqu,int &x){ if(!lqu->front||!lqu->rear)return 0; QNode*p=lqu->front; x=p->data; if(lqu->front==lqu->rear) lqu->front=lqu->rear=NULL; else lqu->front=lqu->front->next; free(p); return 1;}

三、抽象數據類型

Wiki:抽象數據類型Abstract Data Type,ADT)是計算機科學中具有類似行為的特定類別的數據結構的數學模型;或者具有類似語義的一種或多種程序設計語言的數據類型。

可以理解成API的功能定義清晰,但不考慮演算法的實現以及存儲方式的數據結構。

PS:

廣告時間啦~

理工狗不想被人文素養拖後腿?不妨關注微信公眾號:

歡迎掃碼關注~

推薦閱讀:

浙江大學-數據結構-簡單排序-9.1.3
浙江大學-數據結構-小白專場:最小路徑問題-7.1.2
浙江大學-數據結構-選講旅遊規劃-8.3.1
浙江大學-數據結構-小白專場:C語言實現如何建立圖-6.5.1
浙江大學-數據結構-拓撲序列-8.2.1

TAG:數據結構 | 計算機專業 | CC |