棧
棧是一種運算受限的線性表,是一種先進后出的數據結構,限定只能在一端進行插入和刪除操作,允許操作的一端稱為棧頂,不允許操作的稱為棧底
順序棧(順序結構)
順序棧:用一段連續的存儲空間來存儲棧中的數據元素,比較常見的是用數組來實現順序棧
順序存儲結構:1.元素所占的存儲空間必須連續(這里的連續是指的邏輯連續,而不是物理連續)
2.元素在存儲空間的位置是按邏輯順序存放的
(圖片來源:https://www.cnblogs.com/misterge/p/3427587.html)
順序棧的實現一般包括如下部分
代碼聲明部分
#include <stdio.h> #include <stdlib.h>
#define MAX_SIZE 5 /* 棧最大容量 */
#define Empty 0 /* 空 */
#define Full 1 /* 滿 */
#define Avail -1 /* 可用 */ typedef struct sta { int *top; /* 棧頂指針 */
int *bottom; /* 棧底指針 */
int stack_size; /* 棧的最大容量 */ }stack; stack Push (stack p); /* 入棧 */
void DisplyStack (stack p); /* 遍歷棧中元素 */ stack Pop (stack p); /* 出棧 */ stack InitStack (stack p); /* 初始化棧 */
int StackEmpty (stack p); /* 判斷棧是否為空 */
int StackFull (stack p); /* 判斷棧是否為滿 */
一、棧的聲明
第一種:
1 typedef struct sta 2 { 3 int stack[SIZE]; /* 存放棧中元素的一維數組 */
4 int top; /* 存放棧頂元素的下標 */
5 }stack;
(這里只用了一個top來指向棧頂的位置,也可以用兩個變量base、top來分別指向棧空間棧底位置和棧頂位置)
第二種:(本篇隨筆是使用的第二種聲明方式)
1 typedef struct sta 2 { 3 int *top; /* 棧頂指針 */
4 int *bottom; /* 棧底指針 */
5 int stack_size; /* 棧的最大容量 */
6 }stack;
二、棧的初始化
1 /* Function:棧的初始化 */
2 stack InitStack (stack p) 3 { 4 p.bottom = (int *)malloc(p.stack_size * sizeof(int)); 5 if (p.bottom == NULL) 6 { 7 printf("初始化棧失敗\n"); 8 exit(0); 9 } 10 p.top = p.bottom; 11 p.stack_size = MAX_SIZE; 12
13 return p; 14 }
三、入棧(壓棧)
1 /* Function:入棧 */
2 stack Push (stack p) 3 { 4 int data; 5 if (StackFull(p) == Full) 6 { 7 printf("棧空間已滿,無法入棧"); 8 return p; 9 } 10 printf("Please input data"); 11 scanf("%d", &data); 12 *p.top = data; 13 p.top++; 14
15 return p; 16 }
四、出棧
1 /* Function:出棧 */
2 stack Pop (stack p) 3 { 4 if (StackEmpty(p) == Empty) 5 { 6 printf("棧為空棧,無法出棧 "); 7 return p; 8 } 9 p.top--; 10 printf("出棧元素為:%d\n", *p.top); 11
12 return p; 13 }
(棧頂指針指向的位置是棧頂指針的后一個元素,所以在出棧時需要p.top--,才能指向出棧的元素)
五、判斷棧是否為空
1 /* Function:判斷棧是否為空 */
2 int StackEmpty (stack p) 3 { 4 if (p.top == p.bottom) 5 { 6 return Empty; 7 } 8 else
9 { 10 return Avail; 11 } 12 }
六、判斷棧是否為滿
1 /* Function:判斷棧是否為滿 */
2 int StackFull (stack p) 3 { 4 if (p.top - p.bottom == p.stack_size) 5 { 6 return Full; 7 } 8 else
9 { 10 return Avail; 11 } 12 }
七、遍歷棧中的元素
1 /* Function:遍歷棧中元素,從棧頂到棧底*/
2 void DisplyStack (stack p) 3 { 4 if (StackEmpty(p) == Empty) 5 { 6 printf("棧為空棧,無法遍歷\n"); 7 return; 8 } 9 printf("棧中元素為:"); 10 printf("頂端["); 11 while (p.top != p.bottom) 12 { 13 p.top--; 14 printf("%d-", *p.top); 15 } 16 printf("]底端\n"); 17 }
順序棧實現--完整代碼
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define MAX_SIZE 5 /* 棧最大容量 */
5 #define Empty 0 /* 空 */
6 #define Full 1 /* 滿 */
7 #define Avail -1 /* 可用 */
8
9 typedef struct sta 10 { 11 int *top; /* 棧頂指針 */
12 int *bottom; /* 棧底指針 */
13 int stack_size; /* 棧的最大容量 */
14 }stack; 15 stack Push (stack p); /* 入棧 */
16 void DisplyStack (stack p); /* 遍歷棧中元素 */
17 stack Pop (stack p); /* 出棧 */
18 stack InitStack (stack p); /* 初始化棧 */
19 int StackEmpty (stack p); /* 判斷棧是否為空 */
20 int StackFull (stack p); /* 判斷棧是否為滿 */
21
22 int main() 23 { 24 stack p; 25 char ch; 26
27 p.stack_size = MAX_SIZE; 28 p = InitStack (p); /* 初始化棧 */
29 printf("Do you want to push to stack?(Y/N)"); 30 scanf(" %c", &ch); 31 while (ch == 'Y' || ch == 'y') 32 { 33 p = Push (p); /* 入棧 */
34 DisplyStack (p);/* 打印棧中元素 */
35 printf("Do you want to push to stack?(Y/N)"); 36 scanf(" %c", &ch); 37 } 38 printf("Do you want to pop (Y/N)"); 39 scanf(" %c", &ch); 40 while (ch == 'Y' || ch == 'y') 41 { 42 p = Pop (p); 43 DisplyStack (p); 44 printf("Do you want to pop (Y/N)"); 45 scanf(" %c", &ch); 46 } 47
48 return 0; 49 } 50 /* Function:判斷棧是否為空 */
51 int StackEmpty (stack p) 52 { 53 if (p.top == p.bottom) 54 { 55 return Empty; 56 } 57 else
58 { 59 return Avail; 60 } 61 } 62 /* Function:判斷棧是否為滿 */
63 int StackFull (stack p) 64 { 65 if (p.top - p.bottom == p.stack_size) 66 { 67 return Full; 68 } 69 else
70 { 71 return Avail; 72 } 73 } 74 /* Function:入棧 */
75 stack Push (stack p) 76 { 77 int data; 78 if (StackFull(p) == Full) 79 { 80 printf("棧空間已滿,無法入棧"); 81 return p; 82 } 83 printf("Please input data"); 84 scanf("%d", &data); 85 *p.top = data; 86 p.top++; 87
88 return p; 89 } 90 /* Function:出棧 */
91 stack Pop (stack p) 92 { 93 if (StackEmpty(p) == Empty) 94 { 95 printf("棧為空棧,無法出棧 "); 96 return p; 97 } 98 p.top--; 99 printf("出棧元素為:%d\n", *p.top); 100
101 return p; 102 } 103 /* Function:棧的初始化 */
104 stack InitStack (stack p) 105 { 106 p.bottom = (int *)malloc(p.stack_size * sizeof(int)); 107 if (p.bottom == NULL) 108 { 109 printf("初始化棧失敗\n"); 110 exit(0); 111 } 112 p.top = p.bottom; 113 p.stack_size = MAX_SIZE; 114
115 return p; 116 } 117 /* Function:遍歷棧中元素,從棧頂到棧底*/
118 void DisplyStack (stack p) 119 { 120 if (StackEmpty(p) == Empty) 121 { 122 printf("棧為空棧,無法遍歷\n"); 123 return; 124 } 125 printf("棧中元素為:"); 126 printf("頂端["); 127 while (p.top != p.bottom) 128 { 129 p.top--; 130 printf("%d-", *p.top); 131 } 132 printf("]底端\n"); 133 }
棧頂指針的指向有兩種方式,一種是指向棧頂元素的后一元素(本文使用的就是這種),另一種是指向棧頂元素,兩者在判斷棧為空和滿的條件、入棧、出棧時棧頂指針的移動有一些差異