数据结构4:线性表的应用(2)——栈的括号匹配

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

相关文章

数据结构2:链栈 - 掘金 (juejin.cn)

基础知识

    • 定义:栈(Stack)是限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。
    • 存储形式:顺序存储(数组实现)、链式存储(链表实现)
  • 链栈

    • 链栈是采用链式存储结构实现的“栈“,它是一种数据存储结构,可以通过单链表的方式来实现

题目

假设一个字符串中可以包含三种括号:( )[ ]{},且这三种括号可以按任意次序嵌套使用(如:“...[...{...}...[...]...]...(...)” 为合法嵌套,“...[...{... )...[...]...]...(...)”为不合法嵌套)。编写判别给定表达式中所含括号是否正确配对出现的算法,如果是合法嵌套则返回为true,如果是不符合法嵌套则返回为false。

思路

①实现链栈的常规操作:入栈、出栈、栈判空、获取栈顶元素等操作

②对输入的字符串长度进行校验,若为偶数,则继续进行判断,否则,直接输出匹配失败

③依次对字符进行入栈操作,将入栈元素与栈顶元素进行匹配,根据比较的不同结果执行不同的操作。如:匹配,则出栈‘;不匹配,则入栈。

代码

//======================================链栈============================================
class StackNode
{
public:
	StackNode() :data(-1), next(NULL) {}
	StackNode(int m_data, StackNode *m_next = NULL) :data(m_data), next(m_next) {}
	~StackNode() { next = NULL; }
	int data;
	StackNode *next;
};

class LinkStack
{
public:
	LinkStack() :p(NULL), len(0) {}
	~LinkStack() {
		StackEmpty();
	}
	void StackEmpty();  //栈清空
	void Push(int m_data);  //入栈
	int Pop();  //出栈
	StackNode* getTop();  //获得栈顶元素
public:
	StackNode * p;  //空栈,栈顶指针
	int len;
};

void LinkStack::StackEmpty()
{
	while (p != NULL)
	{
		StackNode* tmp = p;
		p = p->next;
		delete tmp;
	}
}

void LinkStack::Push(int m_data)
{
	StackNode* p_new = new StackNode(m_data);
	p_new->next = p;
	p = p_new;
	cout << "整数" << m_data << "入栈成功!" << endl;
	len++;
	cout << "当前链栈为:";
	StackNode* q = p;
	cout << "Start->" << q->data;
	for (;;)
	{
		if (q->next != NULL) {
			cout << "->" << q->next->data;
			q = q->next;
		}
		else break;
	}
	cout << "->End" << endl;
}

int LinkStack::Pop()
{
	if (p == NULL) {
		cout << "此链栈为空,无法执行出栈操作!" << endl;
		return -1;
	}
	int e = p->data;  //取栈顶元素
	StackNode *tmp = p;
	p = p->next;  //指针移到栈顶的下一个结点
	cout << "整数" << e << "出栈成功" << endl;
	len--;
	delete tmp;  //释放栈顶空间

	if (p != NULL)
	{
		cout << "当前链栈为:";
		StackNode* q = p;
		cout << "Start->" << q->data;
		for (;;)
		{
			if (q->next != NULL) {
				cout << "->" << q->next->data;
				q = q->next;
			}
			else break;
		}
		cout << "->End" << endl;
	}
	return e;
}

StackNode* LinkStack::getTop()
{
	return p;
}

//=====================测试2======================
void test2()
{
	cout << "=====================测试2 利用栈检查括号配对======================\n";
	char sign[1000];
	cout << "请输入字符串:";
	cin >> sign;
	int len = strlen(sign);
	cout << len << endl;
	bool flag = true;
	if (len % 2 == 1)
	{
		cout << "输入的字符串长度为奇数!" << endl;
		flag = false;
	}
	else
	{
		sign[len] = '\0';
		cout << "输入的字符串为:";
		for (int i = 0; i < sizeof(sign); ++i)
		{
			if (sign[i] == '\0')
			{
				break;
			}
			else
			{
				if (sign[i] == '{' || sign[i] == '}' || sign[i] == '[' || sign[i] == ']' || sign[i] == '(' || sign[i] == ')')
				{
					cout << sign[i];
				}
				else
				{
					cout << "×";
					flag = false;
					//break;
				}
			}
		}
		cout << "\n字符串长度:" << strlen(sign) << endl;
		cout << "检查输入字符串:" << (flag == 1 ? "无误" : "有误") << endl;
		if (flag == true)
		{
			LinkStack* Slist = new LinkStack;
			for (int i = 0; i < len; ++i)
			{
				Slist->Push(sign[i]);  //入栈
				if (Slist->len >= 2)
				{
					if (Slist->getTop()->data == ')'&&Slist->getTop()->next->data == '(')
					{
						Slist->Pop();
						Slist->Pop();
					}
					else if (Slist->getTop()->data == ']'&&Slist->getTop()->next->data == '[')
					{
						Slist->Pop();
						Slist->Pop();
					}
					else if (Slist->getTop()->data == '}'&&Slist->getTop()->next->data == '{')
					{
						Slist->Pop();
						Slist->Pop();
					}

				}
			}
			if (Slist->len == 0)  //检查括号是否完全匹配
			{
				flag = true;
			}
		}
		cout << "\n实验结果:";
		if (flag == true) cout << "括号->配对<-出现!...\n";
		else cout << "括号->不配对<-出现!...\n";
	}
}

结果

在这里插入图片描述