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

数据结构 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. 栈的应用–括号匹配算法

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

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

猜你喜欢

转载自blog.csdn.net/qq_45770232/article/details/124143164