数据结构与算法课程笔记(四)

本文介绍了栈的基本概念,包括顺序存储结构和链式存储结构的实现,并通过具体实验验证了这两种结构的入栈和出栈操作。此外,还提供了遍历栈的方法及使用链栈判断字符串是否为回文的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验四 栈的实现与应用

实验目的

  1. 栈的顺序存储结构实现;
  2. 栈的链式存储结构实现;
  3. 理解栈的LIFO (后进先出) 特征,并熟练运用栈解决一些实际算法问题。

实验内容

验证题: 用本实验提供的5个文件(.cpp、.h)新建项目,并按以下步骤调试程序,分别验证顺序存储结构和链式存储结构栈的入栈和出栈操作。
1. 顺序存储结构实现栈:
1)入栈bool Push(SqStack &S, ElemType item);
在入栈接口Push(my_stack1,i); 处设置断点①,按“F5”启动调试,按“F10”逐句执行,直到数据1~10全部入栈。程序暂停时观察栈顶数据my_stack1.data[my_stack1.top]和栈顶位置my_stack1.top;

入栈序号栈中全部数据(底至顶排列my_stack1.data栈顶位置my_stack1.top栈顶数据 my_stack1.data [ my_stack1.top]
0-1
1101
21,212
31,2,323
41,2,3,434
51,2,3,4,545
61,2,3,4,5,656
71,2,3,4,5,6,767
81,2,3,4,5,6,7,878
91,2,3,4,5,6,7,8,989
101,2,3,4,5,6,7,8,9,10910

图示:可以看到入栈的过程。(以下实验类似)
在这里插入图片描述
2) 出栈bool Pop(SqStack &S, ElemType &item);
Pop(my_stack1, result); 处设置断点②,按“F5”启动调试,按“F10”逐句执行,直到所有数据完全出栈;

出栈序号栈中全部数据(底至顶排列my_stack1.data栈顶位置my_stack1.top栈顶数据 my_stack1.data [ my_stack1.top]
01,2,3,4,5,6,7,8,9,10910
11,2,3,4,5,6,7,8,989
21,2,3,4,5,6,7,878
31,2,3,4,5,6,767
41,2,3,4,5,656
51,2,3,4,545
61,2,3,434
71,2,323
81,212
9101
10-1

图示:注意:顺序存储时,出栈并不会清除原来存储的值,由top指向栈顶即可。只有当有新值入栈时才会覆盖掉旧值。
在这里插入图片描述
2. 链式存储结构实现栈:

  1. 入栈bool Push(LinkStNode S, ElemType item);
    在入栈接口
    Push(my_stack2,i);* 处设置断点③,按“F5”启动调试,按“F10”逐句执行,直到所有数据全部入栈。当程序暂停时观察栈中各结点的数据、栈顶指针的变化情况;
入栈序号栈中全部数据(底至顶排列)my_stack2栈顶数据 my_stack2->next->data
0
111
21,22
31,2,33
41,2,3,44
51,2,3,4,55
61,2,3,4,5,66
71,2,3,4,5,6,77
81,2,3,4,5,6,7,88
91,2,3,4,5,6,7,8,99
101,2,3,4,5,6,7,8,9,1010

图示:可以看到链栈的入栈过程。
在这里插入图片描述
2) 出栈bool Pop(LinkStNode S, ElemType &item);
Pop(my_stack2, result);处设置断点④*,按“F5”启动调试,按“F10”逐句执行,直到所有数据完全出栈;

出栈序号栈中全部数据(底至顶排列)my_stack2栈顶数据my_stack2->next->data
01,2,3,4,5,6,7,8,9,1010
11,2,3,4,5,6,7,8,99
21,2,3,4,5,6,7,88
31,2,3,4,5,6,77
41,2,3,4,5,66
51,2,3,4,55
61,2,3,44
71,2,33
81,22
911
10

图示:可以看到链栈的出栈过程。出栈时,会清除栈顶结点,释放空间。
在这里插入图片描述
编程题:
1. 设计新接口并在content.cpp文件中测试:
1)设计顺序栈的遍历接口:
void TraverseStack(SqStack S);
实现栈中数据按出栈的顺序输出,但保留栈中的数据;
顺序栈的遍历函数代码如下:

//按出栈顺序遍历栈
void TraverseStack(SqStack S)
{
	if (StackEmpty(S))
	{
		cout<<"栈空"<<endl;
		return; // 栈空,遍历失败
	}
	for (int i=S.top; i>=0; i--)
		cout<<S.data[i]<<" ";
	cout<<endl;
	// 遍历成功
}

2)设计链栈的遍历接口:
void TraverseStack(LinkStNode S);
实现栈中数据按
出栈*的顺序输出,但保留栈中的数据。
//按出栈顺序遍历栈

void TraverseStack(LinkStNode *S)
{
	if (StackEmpty(S))
	{
		cout<<"栈空"<<endl;
		return; //栈空,遍历失败
	}
	LinkStNode *p=S->next; //从头结点后一个位置开始,即从第一个元素结点开始
	while(p)
	{
		cout<<p->data<<" ";
		p=p->next;
	}
	cout<<endl;
	//遍历成功
}

2. 链栈的应用:编写函数,判断给定的字符串是否是“回文”。
如字符串“pop”、“madam”、“level”、“refer”均为中心对称,将中心对称的字符串称为回文。
字符串“abcdba”不中心对称,不是回文。
【要求】利用本实验已实现的链栈基本操作来实现,并进行测试;
【函数原型】bool IsReverse(char *s);
【函数功能】判断字符串s是否为回文,是返回true,否则返回false
【提示】先将字符串中的每个字符依次全部入栈,然后执行出栈操作,依次判断每次出栈的字符是否与字符串中对应正向字符相同,如果出现不相同的情况则说明字符串不是回文,无需继续比较。全部都相同则是回文。

#include "LinkStack.h"

//判断字符串s是否为回文
bool IsReverse(char *s)
{
	LinkStNode *S; //定义管理链栈的栈顶指针
	ElemType t;
	InitStack(S); //初始化链栈
	int i;
	
	for(i=0; s[i]!='\0'; i++) //将字符串中的内容入栈
		Push(S, s[i]);
	
	i=0;
	while( !StackEmpty(S) )
	{
		Pop(S, t); //出栈
		//比较出栈元素与字符串正向元素是否相同
		if (t!=s[i])
			return false;//不是回文
		else
			i++;
	}
	return true; //是回文
}

int main()
{
	char str[20];
	cout<<"输入一个字符串:";
	cin>>str;
	if(IsReverse(str))
		cout<<str<<"是回文"<<endl;
	else
		cout<<str<<"不是回文"<<endl;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青云客_Hugh

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值