只能在一边进出,先进的后出。

进出的一端叫做栈顶,另一端叫做栈底。

栈可以使用顺序存储结构,也能使用链式存储结构。


注意:栈只能在一端进行操作,这是栈的关键特征,也就是说栈不允许在中间进行查找、插入、删除等操作,(但是在实际应用中我们可以打破它)。

这里掌握初始化、入栈、出栈、取栈顶元素操作即可。

顺序存储结构实现栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include<iostream>
using namespace std;

#define MAX_SIZE 128
typedef int DataType;

//栈的结构有多重方式定义,不用局限于这一种
/*
例如:
定义两个int型,并且直接开辟好数组空间
定义一个指针,一个int top
*/
typedef struct _Stack
{
DataType* top; //栈顶指针
DataType* base;//栈底指针
//其实没有必要定义一个来标记元素的个数。
//两个指针指向同一个数组,他们两个相减得到是中间元素的个数。
//否则两个地址相减没有意义
}Stack;

//栈的初始化
bool initStack(Stack& S)
{
//先用栈底指针来拿到这个刚开辟好空间的数组
S.base = new int[MAX_SIZE];//指针来定位这个数组
if (!S.base)
{
return false;
}
S.top = S.base;
return true;
}

//入栈
bool pushStack(Stack& S, DataType data)
{
if (!S.base)
{
return false;
}
if (S.top - S.base == MAX_SIZE)
{
//栈满
return false;
}

//栈中还有空位置
*(S.top) = data;
S.top++;
return true;
}

//出栈-栈顶元素出栈
DataType popStack(Stack& S)
{
//不为空
if (S.top != S.base)
{
return *(--S .top);
}
else
{
return -1;
}
}
//返回栈顶元素
DataType getTop(Stack& S)
{
if (S.top - S.base == 0)
{
return -1;
}
return *(S.top-1);
}
int main(void)
{
Stack S;
initStack(S);
int n = 0;
int m = 0;
cin >> n;
m = n;
while (n)
{
pushStack(S, n);
n--;
}
cout << "____" << endl;
cout << getTop(S) << endl;
cout << "____" << endl;
while (m)
{
cout << popStack(S) << endl;
m--;
}
return 0;
}

入栈操作图示:

image-20211014120918328

链接存储结构实现栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<iostream>
using namespace std;

//数据类型
typedef int DataType;
//最大存储数量
#define MAX_SZIE 128
//结点结构
typedef struct _Snode
{
DataType data;
struct _Snode* next;
}Snode;

//栈(头)结构
typedef struct _Stack
{
int count;
Snode* base;
Snode* top;
}Stack;

//初始化
bool initStack(Stack* S)
{
if (!S)
{
return false;
}
S->base = S->top = NULL;
S->count = 0;
return true;
}

//入栈
bool pushStack(Stack* S, Snode* node)
{
if (!S || !node)
{
return false;
}

//第一次插入元素
if (S->count == 0)
{
S->base = S->top = node;
S->top->next = NULL;
S->count++;
}
else
{
S->top->next = node;
S->top = node;
S->count++;
}
return false;
}
//出栈
bool popStack(Stack* S)
{
if (!S || S->count == 0)
{
return false;
}
Snode* tempnode = S->base;

while (tempnode->next != S->top && S->count != 1)
{
tempnode = tempnode->next;
}
if (S->count == 1)//如果栈中只剩下一个结点可以删除
{
S->base = NULL;
}
//现在tempnode是top的前一个结点
delete S->top;
S->top = tempnode;//如果是最后一个结点的话base和top都被置空了
S->top->next = NULL;

S->count--;
return true;
}
//拿到栈顶元素
bool getTop(Stack* S,DataType* m_data)
{
if (!S || S->count == 0)
{
return S;
}
*m_data = S->top->data;
return false;
}
//判断栈是否为空
bool isEmpty(Stack* S)
{
if (S->count == 0)
{
return true;
}
return false;
}
int main(void)
{
Stack* S = new Stack;
initStack(S);

int n = 5;
int m = n;
while (n)
{
Snode* tempnode = new Snode;
tempnode->data = n;
pushStack(S, tempnode);
n--;
}

while (m >0)
{
m--;
}

cout << S->top->data << " ";
popStack(S);

cout << S->top->data << " ";
popStack(S);

cout << S->top->data << " ";
popStack(S);

cout << S->top->data << " ";
popStack(S);

cout << S->top->data << " ";
popStack(S);

if (!isEmpty(S))
{
cout << S->top->data << " ";
}


int temp = 0;
getTop(S, &temp);
cout << temp << endl;

delete S;
return 0;
}

补充:要修改指针指向地址,可以传递二级指针。

一级指针修改值。

实际应用

迷宫求解

链接——【栈】实现迷宫求解(C++)(详解)

表达式求值

链接——【数据结构】栈(C++)