【数据结构】三、栈的顺序存储(顺序栈)、基本操作以及栈的应用--括号匹配算法 的实现

数据结构 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;
}

结果:
在这里插入图片描述

总结

本文主要包括两块内容:

  1. 顺序栈的c++实现
    • 初始化
    • 判空
    • 进栈
    • 出栈
    • 获取栈顶元素
  2. 栈的应用–括号匹配算法

    算法思想:栈是受限的线性表,利用栈的特点。
    扫描每个字符,
    遇到花、中、圆的左括号时,进栈;
    遇到对应的右括号时,检查栈顶元素是否为对应的左括号;
    若是,退栈;
    否则,匹配错误;
    最后栈不为空,也为错误。

栈是受限的线性表,但“受限”在某些场景下也是另一种“更优”。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LiYikou

您的支持是我最大的动力~♥

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值