郝斌資料結構入門---P30---棧
阿新 • • 發佈:2018-10-31
郝斌資料結構入門---P30---棧
線性結構的常見應用之一:棧(只能頭部插入,頭部刪除)
定義:一種可以實現“ 先進後出 ”的儲存結構,棧類似於箱子
分類:靜態棧,動態棧
演算法:出棧pop,入棧push(壓棧)
應用:函式呼叫,中斷,表示式求值,記憶體分配,緩衝處理,迷宮
為了便於連結串列的操作,產生一個沒有實際含義的頭結點。
初始化棧init()函式:
建立一個空棧,把pTop和pBotoom都指向頭結點
壓棧push()函式:
第一步:先建立一個新的節點
第二步:把val賦給新節點的資料域
第三步:因為每次壓棧到當前棧頂的上方,所以把新節點的指標域指向pTop
第四步:pTop指向新的節點
遍歷輸出traverse()函式:
定義一個指標p,p永遠指向棧頂元素
然後從棧頂到棧底依次遍歷
出棧pop()函式:
把pS所指向的棧出棧一次,並把出棧的元素存入pVal形參所指向的變數中
如果出棧失敗,返回-1,否則返回1
先定義指標r,然後再把pTop往後移一個,最後把r釋放
清空節點clear()函式:
定義兩個指標p和q
p指向棧頂元素,q指向棧頂下一個元素
這樣釋放p,q剛好是下一個元素,然後再把q賦值給p,q往下移一個
程式碼如下:
//動態棧的本質是操作連結串列 #include <stdio.h> #include <malloc.h> #include <stdlib.h> //NODE = struct Node //PNODE = struct Node * typedef struct Node { int data; struct Node * pNext; }NODE, *PNODE; //STACK = struct Stack //PSTACK = struct Satck * //棧裡面有兩個元素pTop,pBottom typedef struct Stack { PNODE pTop; //指向棧的頂部 PNODE pBottom; //指向棧的底部 }STACK, *PSTACK; //PSTACK 等價於 struct Stack * void init(PSTACK); void push(PSTACK, int); void traverse(PSTACK); int pop(PSTACK, int *); void clear(PSTACK pS); int main(void) { STACK S; //STACK 等價於 struct Stack int val; //儲存出棧的元素 init(&S);//初始化棧,目的是造出一個空棧 push(&S, 1);//壓棧 push(&S, 2);//壓棧 push(&S, 3);//壓棧 push(&S, 4);//壓棧 push(&S, 5);//壓棧 push(&S, 6);//壓棧 traverse(&S);//遍歷輸出 clear(&S);//清空節點 traverse(&S);//遍歷輸出 if (pop(&S, &val))//出棧 { printf("出棧成功,出棧的元素是%d\n", val); } else { printf("出棧失敗!\n"); } traverse(&S);//遍歷輸出 return 0; } //初始化目的:建立一個空棧,把pTop和pBotoom都指向頭結點 void init(PSTACK pS) { pS->pTop = (PNODE)malloc(sizeof(NODE)); if (NULL == pS->pTop) { printf("動態記憶體分配失敗!\n"); exit(-1); } else { pS->pBottom = pS->pTop; pS->pTop->pNext = NULL; //pS->pBottom->pNext = NULL; } } //壓棧 //第一步:先建立一個新的節點 //第二步:把val賦給新節點的資料域 //第三步:因為每次壓棧到當前棧頂的上方,所以把新節點的指標域指向pTop //第四步:pTop指向新的節點 void push(PSTACK pS, int val) { PNODE pNew = (PNODE)malloc(sizeof(NODE));//建立新的節點 pNew->data = val; //把val賦給新節點的資料域 pNew->pNext = pS->pTop; //pS->pTop不能改成pS->Bottom pS->pTop = pNew; return ; } //遍歷輸出 //定義一個指標p,p永遠指向棧頂元素 //然後從棧頂到棧底依次遍歷 void traverse(PSTACK pS) { PNODE p = pS->pTop; while (p != pS->pBottom) { printf("%d ", p->data); p = p->pNext; } printf("\n"); return; } //判斷棧是否為空 int empty(PSTACK pS) { if (pS->pTop == pS->pBottom) return 1; else return 0; } //出棧 //把pS所指向的棧出棧一次,並把出棧的元素存入pVal形參所指向的變數中 //如果出棧失敗,返回-1,否則返回1 //先定義指標r,然後再把pTop往後移一個,最後把r釋放 int pop(PSTACK pS, int *pVal) { if (empty(pS)) //pS本身存放的就是S的地址 { return 0; } else//棧是非空 { PNODE r = pS->pTop; *pVal = r->data;//儲存棧頂資料 pS->pTop = r->pNext; free(r); r = NULL; return 1; } } //clear 清空節點 //定義兩個指標p和q //p指向棧頂元素,q指向棧頂下一個元素 //這樣釋放p,q剛好是下一個元素,然後再把q賦值給p,q往下移一個 void clear(PSTACK pS) { if (empty(pS))//空的時候,不需要操作 { return; } else //非空的時候,才需要操作 { PNODE p = pS->pTop; PNODE q = NULL; while (p != pS->pBottom)//不是最後一個元素 { q = p->pNext; free(p); p = q; } pS->pTop = pS->pBottom; } }