目录
数据结构 DATA STRUCTURE
三、栈
3.1 栈的顺序存储结构实现
#define MaxSize 50
typedef char ElemType; // 根据具体情况定义栈内元素数据类型
typedef struct {
ElemType data[MaxSize]; // 用数组来实现存储
int top; // 用int型变量表示指针
}SqStack;
3.2 顺序栈的基本操作实现
1. 初始化
// Initialize Stack
void InitStack(SqStack &S) {
S.top = -1; // init the pointer of top-of-stack
}
2. 判空
// Check if Stack is empty
bool StackEmpty(SqStack S) {
if (S.top == -1)
return true;
else
return false;
}
3. 进栈
// Push element onto the Stack
bool Push(SqStack &S, ElemType x) {
if (S.top == MaxSize - 1)
return false;
S.data[++S.top] = x; // First Addition, Then Push
return true;
}
4. 出栈
// Popup element of Stack
bool Pop(SqStack &S, ElemType &x) {
/*
Why this should add a variable x?And why use the "&"?
Pop doesn't means delete.
Just Read the Top and Top--.
*/
if (S.top == -1)
return false;
x = S.data[S.top--]; // First out,Then --
return true;
}
5. 获取栈顶元素
// Get the Top of Stack
bool GetTop(SqStack &S, ElemType &x) {
// This x is used to Store the Top Elem.
if (S.top == -1)
return false;
x = S.data[S.top];
return true;
}
3.3 栈的应用–括号匹配算法
算法思想:栈是受限的线性表,利用栈的特点。
扫描每个字符,
遇到花、中、圆的左括号时,进栈;
遇到对应的右括号时,检查栈顶元素是否为对应的左括号;
若是,退栈;
否则,匹配错误;
最后栈不为空,也为错误。
代码:
// 3. 括号匹配实现
bool BracketsCheck(string str) {
InitStack(S);
int i = 0; // 循环变量
char e; // 获取出栈元素
while (str[i] != '\0') {
switch(str[i]) {
case '(':
Push(S, '(');
break; // 在switch中,break只能终止距离最近的switch,而不是外面的循环
case '[':
Push(S, '[');
break;
case '{':
Push(S, '{');
break;
case ')':
// if (Pop(S,e) && e == '(')
if (!Pop(S, e) || e != '(') {
// 如果栈空 或者 栈非空但是括号不匹配
cout << "括号不匹配!\n";
return false;
}
break;
case ']':
if (!Pop(S, e) || e != '[') {
cout << "括号不匹配!\n";
return false;
}
break;
case '}':
if (!Pop(S, e) || e != '{') {
cout << "括号不匹配!\n";
return false;
}
break;
default:
break;
}
i++;
}
if (!StackEmpty(S)) {
// 如果栈非空
cout << "括号不匹配!\n";
return false;
}
else {
cout << "括号匹配!\n";
return true;
}
}
全部代码(复制可直接运行)
#include <stdlib.h>
#include <iostream>
using namespace std;
// 1. 定义栈的数据结构
#define MaxSize 50
typedef char ElemType; // 根据具体情况定义栈内元素数据类型
typedef struct {
ElemType data[MaxSize]; // 用数组来实现存储
int top; // 用int型变量表示指针
}SqStack;
// 定义一个 栈 全局变量
SqStack S;
// 2. 栈的运算实现(初始化,判空,入栈,出栈,获取栈顶元素)
// Initialize Stack
void InitStack(SqStack &S) {
S.top = -1; // init the pointer of top-of-stack
}
// Check if Stack is empty
bool StackEmpty(SqStack S) {
if (S.top == -1)
return true;
else
return false;
}
// Push element onto the Stack
bool Push(SqStack &S, ElemType x) {
if (S.top == MaxSize - 1)
return false;
S.data[++S.top] = x; // First Addition, Then Push
return true;
}
// Popup element of Stack
bool Pop(SqStack &S, ElemType &x) {
/*
Why this should add a variable x?And why use the "&"?
Pop doesn't means delete.
Just Read the Top and Top--.
*/
if (S.top == -1)
return false;
x = S.data[S.top--]; // First out,Then --
return true;
}
// Get the Top of Stack
bool GetTop(SqStack &S, ElemType &x) {
// This x is used to Store the Top Elem.
if (S.top == -1)
return false;
x = S.data[S.top];
return true;
}
// 3. 括号匹配实现
bool BracketsCheck(string str) {
InitStack(S);
int i = 0; // 循环变量
char e; // 获取出栈元素
while (str[i] != '\0') {
switch(str[i]) {
case '(':
Push(S, '(');
break; // 在switch中,break只能终止距离最近的switch,而不是外面的循环
case '[':
Push(S, '[');
break;
case '{':
Push(S, '{');
break;
case ')':
// if (Pop(S,e) && e == '(')
if (!Pop(S, e) || e != '(') {
// 如果栈空 或者 栈非空但是括号不匹配
cout << "括号不匹配!\n";
return false;
}
break;
case ']':
if (!Pop(S, e) || e != '[') {
cout << "括号不匹配!\n";
return false;
}
break;
case '}':
if (!Pop(S, e) || e != '{') {
cout << "括号不匹配!\n";
return false;
}
break;
default:
break;
}
i++;
}
if (!StackEmpty(S)) {
// 如果栈非空
cout << "括号不匹配!\n";
return false;
}
else {
cout << "括号匹配!\n";
return true;
}
}
// 4. 主函数测试括号匹配算法
int main() {
string str1 = "[(2*3)+4]-2]]";
cout << BracketsCheck(str1) << endl;
string str2 = "[[[333]";
cout << BracketsCheck(str2) << endl;
string str3 = "]]][";
cout << BracketsCheck(str3) << endl;
return 0;
}
结果:
总结
本文主要包括两块内容:
- 顺序栈的c++实现
- 初始化
- 判空
- 进栈
- 出栈
- 获取栈顶元素
- 栈的应用–括号匹配算法
算法思想:栈是受限的线性表,利用栈的特点。
扫描每个字符,
遇到花、中、圆的左括号时,进栈;
遇到对应的右括号时,检查栈顶元素是否为对应的左括号;
若是,退栈;
否则,匹配错误;
最后栈不为空,也为错误。
栈是受限的线性表,但“受限”在某些场景下也是另一种“更优”。