第一種結構:
存儲空間有限,適用於知道存儲長度的情況下。操作實現很簡單。
1 #include "stdio.h" 2 3 4 #define MAXSIZE 50 5 #define STACKINCREMENT 10 6 #define OK 1 7 #define ERROR 0 8 typedef int SElemType; 9 typedef int Status; 10 11 typedef struct 12 { 13 SElemType data[MAXSIZE]; //存儲數組 14 int top; //棧頂 15 }Stack; 16 17 //初始化棧 18 Status InitStack(Stack &S) 19 { 20 S.top = -1; //棧頂指向-1代表空棧 21 return OK; 22 } 23 24 //重置棧為空棧 25 Status ClearStack(Stack &S) 26 { 27 S.top = -1; //與初始化一樣道理 28 return OK; 29 } 30 31 //判斷棧是否為空,空棧返回OK 否則返回ERROR 32 Status StackEmpty(Stack S) 33 { 34 if(S.top < 0) 35 return OK; 36 else 37 return ERROR; 38 } 39 40 //返回棧的長度 41 int StackLength(Stack S) 42 { 43 return S.top+1; //因為top值是做數組下標所以比長度小一 44 } 45 46 //若棧不為空 用e返回棧頂數據 並返回OK 否則返回ERROR 47 Status GetTop(Stack S, SElemType &e) 48 { 49 if(StackEmpty(S)) 50 return ERROR; 51 e = S.data[S.top]; 52 return OK; 53 } 54 55 //若棧不為空 把e插入棧頂 並返回OK 否則返回ERROR 56 Status Push(Stack &S, SElemType e) 57 { 58 if(S.top >= MAXSIZE-1) 59 return ERROR; 60 S.top++; 61 S.data[S.top] = e; 62 return OK; 63 } 64 65 //若棧不為空 刪除棧頂數據 並用e返回值 並返回OK 否則返回ERROR 66 Status Pop(Stack &S, SElemType &e) 67 { 68 if(StackEmpty(S)) 69 return ERROR; 70 if(StackEmpty(S)) 71 return ERROR; 72 e = S.data[S.top]; 73 S.top--; 74 return OK; 75 } 76 77 //遍歷Visit()函數 78 Status StackTraverse(Stack S, void (* Visit)(SElemType e)) 79 { 80 for (int i = 0; i <= S.top; i++) 81 Visit(S.data[i]); 82 printf("\n"); 83 return OK; 84 } 85 86 //StackTraverse調用函數 87 //在這里為輸出數據 88 void Visit(SElemType e) 89 { 90 printf("%d ", e); 91 }
因為數據是存儲在數組之中,所以沒有銷毀棧的基本操作函數
第二種結構:
相比第一種結構這種方法可以在上限的存儲時增加存儲容量的大小,使用更加靈活。操作實現依舊簡單。
1 #include "stdio.h" 2 #include "stdlib.h" 3 4 typedef int Status; //存儲空間初始分配 5 typedef int SElemType; //存儲空間分配增量 6 #define ERROR 0 7 #define OK 1 8 #define STACK_INIT_SIZE 100 9 #define STACKINCREMENT 10 10 11 typedef struct 12 { 13 SElemType * base; //在棧構造之前和銷毀之后base的值為NULL 14 SElemType * top; //棧頂指針 15 int StackSize; //當前已分配的存儲空間,以元素為單位 16 }Stack; 17 18 //構造一個空棧 19 Status InitStack (Stack &S) 20 { 21 S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); //分配基本空間 22 if(!S.base) //判斷是否分配成功 23 return ERROR; 24 S.top = S.base; //指向棧頂 25 S.StackSize = STACKINCREMENT; //初始鏈表最大長度 26 return OK; 27 }//InitStack 28 29 //銷毀一個棧 30 Status DestroyStack(Stack &S) 31 { 32 free(S.base); //收回空間 33 S.top = S.base = NULL; //棧頂和base均指向空 34 return OK; 35 } 36 37 //重置表為空表 38 Status ClearStack(Stack S) 39 { 40 S.top = S.base;//棧頂指向首位代表表空 41 return OK; 42 } 43 44 //若S為空棧返回OK 否則返回ERROR 45 Status StackEmpty(Stack S) 46 { 47 if (S.top == S.base) 48 return OK; 49 else 50 return ERROR; 51 } 52 53 //返回棧的長度 54 int StackLength(Stack S) 55 { 56 SElemType * p = S.base; 57 int i = 0; //計數值為表長 58 while(p != S.top) 59 { 60 p++; 61 i++; 62 } 63 return i; 64 } 65 66 //若棧不空則用e返回棧頂數據並返回OK否則返回ERROR 67 Status GetTop(Stack S, SElemType &e) 68 { 69 if (StackLength(S) == 0) //空棧 70 return ERROR; 71 e = *S.top; 72 return OK; 73 } 74 75 //插入新的棧頂數據 76 Status Push(Stack &S, SElemType e) 77 { 78 if(S.top - S.base >=S.StackSize) //空間不足 79 { 80 S.base = (SElemType *)realloc(S.base, (S.StackSize + STACKINCREMENT) * sizeof(SElemType)); 81 if(!S.base) 82 return ERROR; 83 S.top = S.base + S.StackSize; 84 S.StackSize += STACKINCREMENT; 85 } 86 S.top++; 87 *S.top = e; 88 return OK; 89 } 90 91 //若棧不空 則刪除棧頂數據並用e返回且返回OK 否則返回ERROR 92 Status Pop(Stack &S, SElemType &e) 93 { 94 if(StackLength(S) == 0) //空棧 95 return ERROR; 96 e = *S.top; 97 S.top--; 98 return OK; 99 } 100 101 //對棧遍歷Visit()函數 102 Status StackTraverse(Stack S, void (*Visit)(SElemType e)) 103 { 104 SElemType * p = S.base; 105 while(p != S.top) 106 Visit(*++p); 107 printf("\n"); 108 return OK; 109 } 110 111 //StackTraverse調用函數 112 //在這里做輸出棧表用 113 //順序為棧底到棧頂 114 void Visit(SElemType e) 115 { 116 printf("%d ",e); 117 }
棧是限定僅在表尾進行插入和刪除的操作線性表,因此棧的實現比較線性表顯得更簡單且容易實現。
參考《數據結構(C語言版)》嚴蔚敏編著