關於棧和隊列的相關操做

一、棧  分爲順序棧和鏈棧  對應數組和鏈表數組

top指向棧頂元素,設置空棧爲-1;存在一個元素時top=0spa

棧的長度爲StackSize.net

定義棧的結構體:指針

 1 #include "stdio.h"
 2 
 3 /* 存儲空間初始分配量 */
 4 #define MAXSIZE 20
 5 
 6 /* SElemType類型根據實際狀況而定,這裏假設爲int */
 7 typedef int SElemType;
 8 
 9 /* 順序棧結構 */
10 typedef struct
11 {
12     SElemType data[MAXSIZE];
13     int top; /* 用於棧頂指針 */
14 }SqStack;
15 
16 int main()
17 {
18 }

進棧操做:pushcode

1 int Push(SqStack * S, SElemType e){
2     if(S->top == MAXSIZE-1){
3         //棧滿
4         return 0;
5     }
6     S->top++;
7     S->data[S->top] = e;
8     return 1;
9 }

初始化一個空棧:blog

//初始化棧
int InitStack(SqStack S){
    S->top = -1;
    return 1;
}

棧的遍歷:內存

 1 /* 從棧底到棧頂依次對棧中每一個元素顯示 */
 2 Status StackTraverse(SqStack S)
 3 {
 4     int i;
 5     i=0;
 6     while(i<=S.top)
 7     {
 8         visit(S.data[i++]);
 9     }
10     printf("\n");
11     return OK;
12 }
13 
14 Status visit(SElemType c)
15 {
16     printf("%d ",c);
17     return OK;
18 }

注:S->top表明着棧對應數組的下標0,1,2 。。。get

出棧:it

1 int Pop(SqStack* S, SElemType* e){
2     if(-1 == S->top){
3         return 0;
4     }
5     *e = S->data[S->top];
6     S->top--;
7     return 1;
8 }

獲取棧頂元素:io

1 /* 若棧不空,則用e返回S的棧頂元素,並返回OK;不然返回ERROR */
2 Status GetTop(SqStack S,SElemType *e)
3 {
4     if (S.top==-1)
5         return ERROR;
6     else
7         *e=S.data[S.top];
8     return OK;
9 }

判斷棧是否爲

1 /* 若棧S爲空棧,則返回TRUE,不然返回FALSE */
2 Status StackEmpty(SqStack S)
3 {
4     if (S.top==-1)
5         return TRUE;
6     else
7         return FALSE;
8 }

置空棧:

1 /* 把S置爲空棧 */
2 Status ClearStack(SqStack *S)
3 {
4     S->top=-1;
5     return OK;
6 }

二、鏈棧

鏈棧對應不含頭結點的單鏈表

top表明指向棧頂的指針,這裏和鏈表中的next合併爲一個,當top=null時,鏈棧爲空

定義鏈棧的結構體:

下面是單鏈表的結構體:

1 typedef struct Node
2 {
3     ElemType data;
4     struct Node *next;
5 }Node;
6 typedef struct Node *LinkList; /* 定義LinkList */

類似的鏈棧的結構體爲:

1 /* 鏈棧結構 */
2 typedef struct StackNode
3 {
4     SElemType data;
5     struct StackNode *next;
6 } StackNode,*LinkStackPtr;

這只是鏈棧一個節點的定義,還須要添加鏈棧的棧頂指針:

 1 typedef int Status;
 2 /* SElemType類型根據實際狀況而定,這裏假設爲int */
 3 typedef int SElemType;
 4 
 5 /* 鏈棧結構 */
 6 typedef struct StackNode
 7 {
 8     SElemType data;
 9     struct StackNode *next;
10 } StackNode,*LinkStackPtr;
11 
12 typedef struct
13 {
14     LinkStackPtr top;
15     int count;
16 } LinkStack;

其中count是用來計算棧中元素的個數的,也能夠根據須要添加屬性等

入棧,其實就是添加新的節點,下面這張圖描述的很清楚:

實際上就兩步:一、將新的節點next指向原棧頂元素  二、將top指針指向新的節點

1 int Push(LinkStack* L, SElemType e){
2     //首先分配節點
3     LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
4     p->data = e;
5     p->next = S->top;
6     S->top = p;
7     S->count++;
8     return 1;
9 }

初始化空棧:條件count=0,且top爲null

 1 /*  構造一個空棧S */
 2 Status InitStack(LinkStack *S)
 3 {
 4     S->top = (LinkStackPtr)malloc(sizeof(StackNode));
 5     if(!S->top)
 6         return ERROR;//分配失敗
 7     S->top=NULL;
 8     S->count=0;
 9     return OK;
10 }

遍歷的過程和鏈表徹底相似,這裏再也不贅述:

 1 Status StackTraverse(LinkStack S)
 2 {
 3     LinkStackPtr p;
 4     p=S.top;
 5     while(p)
 6     {
 7         visit(p->data);
 8         p=p->next;
 9     }
10     printf("\n");
11     return OK;
12 }
13 
14 Status visit(SElemType c)
15 {
16     printf("%d ",c);
17     return OK;
18 }

出棧操做:這裏主要注意一點就是刪除的節點要釋放掉 核心代碼就是S->top = S->top->next;

 1 /* 若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;不然返回ERROR */
 2 Status Pop(LinkStack *S,SElemType *e)
 3 {
 4     LinkStackPtr p;
 5     if(StackEmpty(*S))
 6         return ERROR;
 7     *e=S->top->data;
 8     p=S->top;                    /* 將棧頂結點賦值給p,見圖中① */
 9     S->top=S->top->next;    /* 使得棧頂指針下移一位,指向後一結點,見圖中② */
10     free(p);                    /* 釋放結點p */
11     S->count--;
12     return OK;
13 }

注:這裏的Status是預約義的,這裏簡化表示int

置空鏈棧會比順序棧稍微複雜一些:置空順序棧只需一步S->top = -1便可,而對於鏈棧置空實質上就是刪除整個鏈表全部的節點,這裏關鍵的問題就是移動待刪除節點指針到下一個位置後,無法直接free掉,這樣提及來很差理解,直接看代碼:

 1 /* 把S置爲空棧 */
 2 Status ClearStack(LinkStack *S)
 3 {
 4     LinkStackPtr p,q;
 5     p=S->top;
 6     while(p)
 7     {
 8         q=p;
 9         p=p->next;
10         free(q);
11     }
12     S->count=0;
13     return OK;
14 }

其實就是先將待刪除節點付給一個臨時指針,而後當前指針移動到下一個位置後,就能夠將這個臨時指針給free掉

那這裏來分析一下順序棧和鏈棧的區別:二者的時間複雜度都爲O(1)
順序棧定位元素更加方便,需提早分配內存區域;鏈棧在內存充足的狀況下大小是無限的,存取定位沒有順序棧快,每一個節點還有指針域,某種程度上增長了空間開銷

因此根據不一樣狀況選擇

相關文章
相關標籤/搜索