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