【数据结构与算法】【C++】链栈实验报告

目录

阅读建议:

一、实验目的

二、实验内容

三、实验过程

四、代码结构

五、测试结果


阅读建议:

1.实验的软硬件环境要求:

(1)硬件环境要求:PC机
(2)软件环境要求:Windows 环境下的 Microsoft Visual Studio

2.该实验采用了头文件(.h)和源文件(.cpp)相结合的形式。


一、实验目的

1.熟练掌握栈的链式存储结构的实现;

2.熟练掌握链栈的基本操作算法实现,包括建栈、入栈、出栈、读栈顶元素和释放栈等;

3.灵活使用栈来解决具体的问题。


二、实验内容

1.定义链栈类,封装链栈的基本操作算法;(建议将链栈的类模板及实现算法单独写入.h头文件中);

2.利用链栈的基本操作与特性,从以下题目中选择一个完成:

(1)十进制数转换为二、八、十六进制数

(2)算术表达式的括号匹配合法性判断(表达式中包括的括号类型有圆括号()、方括号[]以及花括号{})

(3)简单算术表达式求值。(表达式里包含运算数、+、-、*、/四类运算符及小括号())


三、实验过程

1.结点结构

template 
struct Node
{
	T data;  //数据域
	Node* next;  //指针域
};

2.构造函数,初始化一个空的链栈。

工作原理:在链栈中,top通常表示栈顶元素,而这里将其初始化为NULL,意味着一开始这个链栈是空的,没有栈顶元素。

template
LinkStack::LinkStack() 
{
	top = NULL;  //初始化栈顶指针为空  
}

3.析构函数,删除LinkStack对象时,自动清理其占用的内存资源。

工作原理:代码遍历了链栈中的所有节点,并释放了它们所占用的内存。这是通过一个循环实现的,循环条件是top != NULL,即只要栈顶指针不为空,就继续循环。在循环中,首先将当前栈顶指针赋值给p,然后将top指向下一个节点,接着删除p指向的节点。这样,所有的节点都会被遍历并释放,从而确保链栈所占用的内存被正确地释放。

template
LinkStack::~LinkStack() 
{
	Node* p = NULL;
	while (top != NULL) {
		p = top;
		top = top->next;
		delete p;
	}
}

4.入栈操作,将一个元素压入链栈的栈顶。

工作原理:首先创建一个新的节点指针p并初始化为NULL。然后通过new操作符动态分配内存,并将新节点的指针赋值给p。接着,将元素x赋值给新节点的数据域,并将新节点的next指针指向当前的栈顶元素(即top)。最后,更新栈顶指针top,使其指向新节点,完成压栈操作。

template
void LinkStack::Push(T x)
{
	Node* p = NULL;
	p = new Node;
	p->data = x;
	p->next = top;
	top = p;  //将p插在栈顶
}

5.出栈操作,从链栈的栈顶弹出元素,并返回其值。

工作原理:首先创建一个新的节点指针p并初始化为NULL,以及一个变量x用于存储弹出元素的值。然后,通过一个if语句检查栈是否为空。如果栈为空(即栈顶指针topNULL),则抛出一个异常,表示下溢。

如果栈不为空,则将栈顶节点的数据域赋值给变量x,并将栈顶指针top暂存到指针变量p中。接着,将栈顶指针top更新为下一个节点,即将栈顶节点从链表中摘除。最后,释放暂存的栈顶节点的内存,并返回弹出元素的值。

template
T LinkStack::Pop()
{
	Node* p = NULL;
	T x;
	if (top == NULL) {
		throw "下溢";
	}
	x = top->data;
	p = top;  //暂存栈顶元素
	top = top->next;  //将栈顶节点摘除
	delete p;
	return x;
}

6.读栈顶元素,获取链栈的栈顶元素的值,如果链栈为空则返回-1。

工作原理:首先通过一个if语句检查链栈是否为空。如果链栈为空(即栈顶指针topNULL),则输出一个错误信息并返回-1。

如果链栈不为空,则直接返回栈顶节点的数据域的值。

template
T LinkStack::GetTop()
{
	if (Empty()) {
		cout << "栈链为空!" << endl;
		return -1;
	}
	return top->data;
}

7.判断链栈是否为空。

工作原理:函数返回一个布尔值,如果链栈的栈顶指针topNULL,即链栈为空,则返回true;否则返回false

template
bool LinkStack::Empty()
{
	return top == NULL;
}

8.检查括号是否匹配。

工作原理:函数接受两个字符参数lr,分别表示左括号和右括号。函数通过一个if语句判断左括号和右括号是否匹配,如果匹配则返回true,否则返回false

template
bool LinkStack::isPaired(char l, char r) 
{
	if ((l == '(' && r == ')') || (l == '[' && r == ']') || (l == '{' && r == '}'))
		return true;
	else
		return false;
}

9.检查表达式的括号是否匹配。

工作原理:函数接受一个字符串参数expr,表示待判断的表达式。函数首先创建一个空的链栈s,然后遍历表达式中的每个字符。对于每个左括号(即([{),将其压入栈中;对于每个右括号(即)]}),首先检查栈是否为空。如果栈为空,则表达式不合法,返回false。如果栈不为空,但当前右括号与栈顶的左括号不匹配,则表达式不合法,返回false

在遍历完表达式中的所有括号后,继续检查栈中是否还有剩余的左括号。如果有,则将栈中的每个左括号与一个虚拟的右括号(用NULL表示)进行匹配检查。如果某个左括号与虚拟的右括号不匹配,则表达式不合法,返回false;如果表达式中的所有括号都匹配合法,则返回true

template
bool LinkStack::ParenthesesMatch(string expr)
{
	LinkStack s;
	for (char c : expr) {
		if (c == '(' || c == '[' || c == '{') {
			s.Push(c);
		}
		else if (c == ')' || c == ']' || c == '}') {
			if (s.Empty()==true) {
				return false;
			}
			else if (isPaired(s.Pop(), c)==false) {
				return false;
			}
		}
	}
	while (!s.Empty()) {
		if (isPaired(s.Pop(), NULL) == false) {
			return false;
		}
	}
	return true;
}

四、代码结构

【数据结构与算法】【C++】链栈实验报告_第1张图片


五、测试结果

1.基本操作

【数据结构与算法】【C++】链栈实验报告_第2张图片

2.算术表达式的括号匹配合法性判断

【数据结构与算法】【C++】链栈实验报告_第3张图片

【数据结构与算法】【C++】链栈实验报告_第4张图片


        完整代码链接:https://download.csdn.net/download/weixin_73286497/88758690

        希望大家可以在该篇实验报告中有所收获,同时也感谢各位大佬的支持。文章如有任何问题请在评论区留言斧正,鸿蒙会尽快回复您的建议!

你可能感兴趣的:(数据结构,#,C++,数据结构,算法,c++,visual,studio)