栈
栈是一种运算受限的线性表,是一种先进后出的数据结构,限定只能在一端进行插入和删除操作,允许操作的一端称为栈顶,不允许操作的称为栈底
顺序栈(顺序结构)
顺序栈:用一段连续的存储空间来存储栈中的数据元素,比较常见的是用数组来实现顺序栈
顺序存储结构: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 }
栈顶指针的指向有两种方式,一种是指向栈顶元素的后一元素(本文使用的就是这种),另一种是指向栈顶元素,两者在判断栈为空和满的条件、入栈、出栈时栈顶指针的移动有一些差异