標籤:資料結構 c語言 棧
寫程式的時候,我們經常會說基本類型變數存在棧記憶體,參考型別的變數(對象,數組)存在堆記憶體。現在我們來看看棧這種資料結構是怎麼實現的。
定義
一種可以實現“先進後出” 的儲存結構
棧類似於往箱子放衣服,先放的最後拿
棧的分類:
靜態棧:以數組方式實現,刪除時刪除下標最大的,插入時從最大下標+1插入
動態棧:以鏈表方式實現,刪除和插入都是從頭部
演算法:出棧(POP),入棧(PUSH)應用:
1. 函數調用 :在函數f中調用另一個g函數,在g函數中調用k函數
執行到要調用g函數位置,先把g函數執行後下一句的地址以及變數壓棧,執行g函數,執行到調用k函數的位置,再把k函數執行後的下一句壓棧,然後執行k函數,執行後取出棧頂元素,賦給CPU,執行g函數中調用k函數後的下一句。
2.中斷
3.運算式求值:3*2+5/6-4兩個棧實現,一個放運算子,一個放資料
4.記憶體配置:把函數形參壓入棧中
5.緩衝處理
6.走迷宮
C語言實現:
下面是C語言實現動態棧的代碼,為了方便在棧底部建立一個頭結點,不存有效資料。先看圖:
#include<stdio.h>#include<malloc.h>#include<stdbool.h>//棧有一個不存放有效資料的前端節點,Pbotom始終指向頭結點。/****定義節點的結構體*/ typedef struct Node{ int data;//資料域 struct Node * PNext;//指標域} Node,*PNext;/****定義棧的結構體*/typedef struct Stack { PNext top;PNext bottom;}Stack,* PStack;/****初始化棧*/void init(PStack PStack ){ //建立一個不存任何有限元素的頭結點,作為棧底 PStack->bottom=malloc(sizeof(Node)); PStack->top=PStack->bottom; PStack->top->PNext=NULL;}/***遍曆棧**/void traverse(PStack Ps ){ if(Ps->bottom==Ps->top) { printf("棧為空白\n"); return ; } PNext pt=Ps->top; while(pt!=Ps->bottom)//不能把pt換成ps->top這樣就修改了鏈表。尷尬。。 { printf("%d ",pt->data); pt=pt ->PNext; } printf("\n"); return ;}/****入棧*/void push(PStack Pstack,int val){ PNext Pnew=malloc(sizeof(Node));//產生一個新節點 Pnew->data=val; Pnew->PNext=Pstack->top; Pstack->top=Pnew;}/****出棧*/void pop(PStack ps ){ if(ps->top==ps->bottom) { printf("棧為空白,無法完成出棧操作\n"); return; } PNext temp=ps->top;//引入輔助變數,用於釋放記憶體 ps->top=ps->top->PNext; free(temp); temp=NULL;}/****清空棧*/void clear(PStack ps){ while(ps->top!=ps->bottom) { PNext temp=ps->top; ps->top=ps->top->PNext; free(temp); }}int main(){Stack stack;init(&stack);push(&stack,6);push(&stack,7);push(&stack,8);traverse(&stack); pop(&stack);traverse(&stack);clear(&stack);traverse(&stack);push(&stack,7);traverse(&stack);return 0;}
資料結構基礎(4)C語言實現棧--鏈式儲存(動態棧)