数据结构(C语言)代码实现(八)——顺序栈实现数值转换行编辑程序括号分配汉诺塔

目录

 参考资料

顺序栈的实现

头文件SqStack.h(顺序栈函数声明)

源文件SqStack.cpp(顺序栈函数实现)

顺序栈的三个应用

数值转换

行编辑程序

顺序栈的实现测试

栈与递归的实现(以汉诺塔为例)


 参考资料

1.本文文章结构参考这篇博客,部分代码也引用自这篇博客。

2021-9-22【数据结构/严蔚敏】【顺序栈&链式栈&迷宫求解&表达式求值】【代码实现算法3.1-3.5】_数据结构表达式求值代码严老师-CSDN博客

2.又搜到一个更靠谱的,这个的引用也用指针替代了。

栈和队列-数据结构与算法(C语言版)_调用pop(&s,&e)函数,让队头数据出队,赋值给参数e,printf输出e-CSDN博客3. 数据结构课本严蔚敏版。

顺序栈的实现

头文件SqStack.h(顺序栈函数声明)

#pragma once
#include <cstdio>
#include <cstdlib>
#include <cstring>#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//Status是函数的类型,其值是函数结果状态代码
typedef int SElemType;//-----栈的顺序存储表示-----
#define STACK_INIT_SIZE 100  //存储空间初始分配量
#define STACKINCREMENT 10    //存储空间分配增量
typedef struct SqStack {SElemType* base;//在栈构造之前和销毁之后,base的值为NULLSElemType* top; //栈顶指针int stacksize;  //当前已分配的存储空间,以元素为单位
}SqStack;
//-----基本操作的函数原型说明-----
Status InitStack(SqStack& S);
//构造一个空栈S
Status DestroyStack(SqStack& S);
//销毁栈S,S不再存在
Status ClearStack(SqStack& S);
//把S置为空栈
Status StackEmpty(SqStack S);
//若栈S为空栈,则返回TRUE,否则返回FALSE
int StackLength(SqStack S);
//返回S的元素个数,即栈的长度
Status GetTop(SqStack S, SElemType& e);
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status Push(SqStack& S, SElemType e);
//插入元素e为新的栈顶元素
Status Pop(SqStack& S, SElemType& e);
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status StackTraverse(SqStack S, void(*visit)(SElemType));
//从栈顶到栈底依次对栈中每个元素调用函数visit()。一旦visit()失败,则操作失败

源文件SqStack.cpp(顺序栈函数实现)

源文件SqStack.cpp是头文件SqStack.h的实现。

#include "SqStack.h"//-----基本操作的函数算法描述(部分)-----
Status InitStack(SqStack& S) {//构造一个空栈SS.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!S.base)exit(OVERFLOW);//存储分配失败,警告C6011S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
}Status DestroyStack(SqStack& S) {free(S.base);S.top = S.base = NULL;S.stacksize = 0;return OK;
}Status ClearStack(SqStack& S) {if (!S.base)return ERROR;S.top = S.base;return OK;
}Status StackEmpty(SqStack S) {if (S.base == S.top)return OK;return ERROR;
}int StackLength(SqStack s) {if (!s.base)return ERROR;return (int)(s.top - s.base);
}Status GetTop(SqStack s, SElemType& e) {//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif (s.base == s.top)return ERROR;e = *(s.top - 1);return OK;
}Status Push(SqStack& s, SElemType e) {//插入元素e为新的栈顶元素if (!s.base)return ERROR;if (s.top - s.base >= s.stacksize) {//栈满,追加存储空间s.base = (SElemType*)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(SElemType));if (!s.base)exit(_OVERFLOW);//存储分配失败s.top = s.base + s.stacksize;s.stacksize += STACKINCREMENT;}*s.top++ = e;//*s.top=e; s.top++;return OK;
}Status Pop(SqStack& s, SElemType& e) {//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif (!s.base || s.top == s.base) return ERROR;e = *--s.top;//--s.top; e=*s.top;return OK;
}Status StackTraverse(SqStack s, void (*visit)(SElemType)) {SElemType* p = s.base;if (!s.base)return ERROR;while (p < s.top)visit(*p++);printf("\n");return OK;
}

顺序栈的四个应用

数值转换

源文件conversion.cpp

#include "SqStack.h"void conversion() {//对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数SqStack S;InitStack(S);//构造空栈SElemType N,e;scanf_s("%d", &N);if (N == 0)//当N为0时下面的while循环不输出{printf("%d", N);return;}while (N) {Push(S, N % 8);N = N / 8;}while (!StackEmpty(S)) {Pop(S, e);printf("%d", e);}
}
int main()
{conversion();return 0;
}//算法3.1

测试结果(课本样例)

括号匹配

栈和队列-数据结构与算法(C语言版)_调用pop(&s,&e)函数,让队头数据出队,赋值给参数e,printf输出e-CSDN博客源文件 MatchBrackets.cpp

完整代码

#include "SqStack.h"/** 括号匹配* 注意将ElemType 修为 char*/
Status MatchBrackets(SqStack& S, char* brackets) {SElemType ch;int len = strlen(brackets);for (int i = 0; i < len; i++) {if (brackets[i] == '{' || brackets[i] == '[' || brackets[i] == '(') {Push(S, brackets[i]);}if (brackets[i] == '}' || brackets[i] == ']' || brackets[i] == ')') {if (StackEmpty(S)) {printf("右括号多于左括号\n");return ERROR;}else {GetTop(S, ch);if (ch == '{' && brackets[i] == '}' || ch == '[' && brackets[i] == ']' || ch == '(' && brackets[i] == ')') {Pop(S, ch);}}}}if (!StackEmpty(S))printf("左括号多于右括号\n");elseprintf("括号匹配成功!");return OK;
}int main()
{SqStack S;char brackets[81] = { 0 };//用char* brackets;会报错InitStack(S);scanf_s("%s", brackets,sizeof(brackets));//不知道为什么,不加sizeof(),括号匹配函数len一直为0,//导致输出总是“括号匹配成功”。MatchBrackets(S, brackets);return 0;
}

 测试结果

行编辑程序

源文件LineEdit.cpp

本来想两个主函数能不能在同一个工程下运行,结果不可以。接着我把数值转换这个主函数移除,发现可以运行行编辑程序这个代码了。

右键conversion.cpp,点击移除。

接着打开LineEdit.cpp。右键点击源文件,在添加中找到现有项,点击现有项寻找即可(前提是你写了)

下面是完整代码

#include "SqStack.h"void visit(SElemType e) {printf("%d ", e);
}void LineEdit() {//利用字符栈S,从终端接收一行并传送至调用过程的数据区SqStack S;InitStack(S);//构造空栈SSElemType c;char ch = getchar();//从终端接收第一个字符while (ch != EOF) {//EOF为全文结束符,Ctrl+z+回车键对应EOFwhile (ch != EOF && ch != '\n') {//一行内switch (ch) {case'#':Pop(S, c);break;//仅当栈非空时退栈case'@':ClearStack(S);break;//重置S为空栈default:Push(S, ch);break;//有效字符进栈,未考虑栈满情形}ch = getchar();//从终端接收下一个字符}//将从栈底到栈顶的栈内字符传送至调用过程中的数据区StackTraverse(S, visit);//课本没有,但我看不到结果,便加上了这个函数ClearStack(S);//重置S为空栈if (ch != EOF)ch = getchar();}DestroyStack(S);
}
int main()
{LineEdit();return 0;
}

测试样例选自课本P49页右下角两行字符,测试结果如下:

此时正常返回。从元素个数看,结果正确,但不直观,所以将SElemType改为char类型。

为了实现行编辑程序,特别修改两处代码(仅在行编辑程序中使用)。

typedef char SElemType;//修改SqStack.h第13行void visit(SElemType e) {printf("%c", e);
}//修改LineEdit.cpp第4行

最终结果 

顺序栈的实现测试

源文件test.cpp ,这个是我复制粘贴的我参考的博客。

#include "SqStack.h"
#include <iostream>
using namespace std;void visit(SElemType e) {printf("%d ", e);
}
//简单测试主函数
int main() {SqStack s;cout << "InitStack" << endl;InitStack(s);cout << "StackEmpty" << endl;StackEmpty(s) ? cout << "yes\n" : cout << "no\n";cout << "Push" << endl;for (int i = 1; i <= 6; i++)Push(s, i);cout << "StackTraverse" << endl;StackTraverse(s, visit);cout << "StackLength" << endl;cout << StackLength(s) << endl;cout << "Pop" << endl;SElemType e;Pop(s, e);cout << e << endl;StackTraverse(s, visit);cout << "GetTop" << endl;GetTop(s, e);cout << e << endl;return 0;
}

测试结果

栈与递归的实现(以汉诺塔为例)

这里课本的代码没有用栈实现递归,但一直在强调递归函数是通过栈实现的,并从栈的角度解释了递归函数的原理。

源文件hanoi.cpp

#include <cstdio>
#include <cstdlib>
#include <cstring>int C = 0;
void move(char x, int n, char z) {printf("%d. Move disk %d from %c to %c\n", ++C, n, x, z);
}
void hanoi(int n, char x, char y, char z)
//将塔座x上按直径由小到大且自上而下编号为1至n的n个圆盘按规则搬到
//塔座z上,y可用作辅助塔座。
//搬动操作move(x, n, z) 可定义为(c是初值为0的全局变量,对搬动计数):
//printf(" %i. Move disk %i from %c to %c\n", ++c, n, x, z);
{if (n == 1)move(x, 1, z);//将编号为1的圆盘从x移到zelse {hanoi(n - 1, x, z, y);//将x上编号为1至n-1的圆盘移到y,z作辅助塔move(x, n, z);        //将编号为n的圆盘从x移到zhanoi(n - 1, y, x, z);//将y上编号为1至n-1的圆盘移到z,x做辅助塔}
}
int main()
{int n=3;char A='a', B='b', C='c';hanoi(n, A, B, C);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/256896.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024-02-13 Unity 编辑器开发之编辑器拓展4 —— EditorGUIUtility

文章目录 1 EditorGUIUtility 介绍2 加载资源2.1 Eidtor Default Resources2.2 不存在返回 null2.3 不存在则报错2.4 代码示例 3 搜索框查询、对象选中提示3.1 ShowObjectPicker3.2 PingObject3.3 代码示例 4 窗口事件传递、坐标转换4.1 CommandEvent4.2 GUIPoint 和 ScreenPoi…

Vue源码系列讲解——模板编译篇【三】(HTML解析器)

目录 1. 前言 2. HTML解析器内部运行流程 3. 如何解析不同的内容 3.1 解析HTML注释 3.2 解析条件注释 3.3 解析DOCTYPE 3.4 解析开始标签 3.5 解析结束标签 3.6 解析文本 4. 如何保证AST节点层级关系 5. 回归源码 5.1 HTML解析器源码 5.2 parseEndTag函数源码 6. …

【快速上手QT】02-学会查看QT自带的手册QT助手

QT助手 为什么大家都说QT简单&#xff0c;第一点就是确实简单&#xff08;bushi&#xff09;。 我个人觉得最关键的点就是人家QT官方就给你准备好了文档&#xff0c;甚至还有专门的IDE——QtCreator&#xff0c;在QTCreator里面还有很多示例代码&#xff0c;只要你会C的语法以…

ETL是什么,有哪些ETL工具?就业前景如何?

ETL是什么 ETL&#xff08;Extract-Transform-Load&#xff09;&#xff0c;用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目标端的过程。ETL一词较常用在数据仓库&#xff0c;但其对象并不限于数据仓库。它可以自动化数据处理过程&#xff0c;减少…

2024.2.3 作业

1、实现单向循环链表的头插头删尾插尾删 #include<stdio.h> #include<string.h> #include<stdlib.h> typedef int datatype; typedef struct node {//数据域int data;//指针域struct node *next; }*Linklist; Linklist create() {Linklist s(Linklist)mallo…

如何在C# Windows Forms应用程序中实现控件之间的连接线

帮我实现绘图工具多个控件连接线&#xff0c;请用c#代码实现 实现绘图工具中多个控件之间的连接线功能&#xff0c;可以通过以下几个步骤来进行&#xff1a; 定义连接线的数据模型&#xff1a;首先需要定义一个模型来表示连接线&#xff0c;这个模型应该包含起点和终点的坐标。…

内网穿透 | 推荐两个免费的内网穿透工具

目录 1、简介 2、Ngrok 2.1、下载安装 2.2、运行 2.3、固定域名 2.4、配置多服务 3、cpolar 3.1、下载安装 3.2、运行 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应…

【AutoML】AutoKeras 进行 RNN 循环神经网络训练

由于最近这些天都在人工审查之前的哪些问答数据&#xff0c;所以迟迟都没有更新 AutoKeras 的训练结果。现在那部分数据都已经整理好了&#xff0c;20w 的数据最后能够使用的高质量数据只剩下 2k。这 2k 的数据已经经过数据校验并且对部分问题的提问方式和答案内容进行了不改变…

【龙年大礼】| 2023中国开源年度报告!

【中国开源年度报告】由开源社从 2015 年发起&#xff0c;是国内首个结合多个开源社区、高校、媒体、风投、企业与个人&#xff0c;以纯志愿、非营利的理念和开源社区协作的模式&#xff0c;携手共创完成的开源研究报告。后来由于一些因素暂停&#xff0c;在 2018 年重启了这个…

基于Qt的人脸识别项目(功能:颜值检测,口罩检测,表情检测,性别检测,年龄预测等)

目录 效果展示代码讲解(待更新)需求一.创建项目二.导入Qt中的摄像头包查看QCamera类的帮助文档三.导入QCameraViewfinder调用百度AI接口完整代码链接完整代码链接在文章末尾 效果展示

react+antd+CheckableTag实现Tag标签单选或多选功能

1、效果如下图 实现tag标签单选或多选功能 2、环境准备 1、react18 2、antd 4 3、功能实现 原理: 封装一个受控组件&#xff0c;接受父组件的参数&#xff0c;数据发现变化后&#xff0c;回传给父组件 1、首先&#xff0c;引入CheckableTag组件和useEffect, useMemo, use…

CSS之水平垂直居中

如何实现一个div的水平垂直居中 <div class"content-wrapper"><div class"content">content</div></div>flex布局 .content-wrapper {width: 400px;height: 400px;background-color: lightskyblue;display: flex;justify-content:…

在Linux系统中设置全局HTTP代理的步骤与技巧

在Linux系统中&#xff0c;设置全局HTTP代理可以方便我们统一管理和控制网络请求。这不仅可以帮助我们加速网络访问&#xff0c;还可以在某些情况下绕过网络限制或实现匿名上网。下面&#xff0c;我将为你详细介绍在Linux系统中设置全局HTTP代理的步骤与技巧。 步骤一&#xf…

【c++】内联函数

Hello everybody!今天咱们来讲一下内联函数&#xff0c;它在某些方面还是很有用的&#xff01; 1.定义 以inline修饰的函数叫做内联函数&#xff0c;编译时c编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。…

mysql8.0.36主从复制(读写分离)配置教程

1、关闭防火墙 使用命令行关闭防火墙 在Ubuntu系统中&#xff0c;可以使用以下命令关闭防火墙&#xff1a; sudo ufw disable执行该命令后&#xff0c;系统会提示是否要关闭防火墙&#xff0c;确认后即可关闭防火墙。 查看防火墙状态 使用以下命令可以查看防火墙当前的状…

apk反编译修改教程系列---简单修改apk默认横竖屏显示 手机端与电脑端同步演示【十一】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…

【python量化交易】qteasy使用教程02 - 获取和管理金融数据

qteasy教程2 - 获取并管理金融数据 qteasy教程2 - 获取并管理金融数据开始前的准备工作获取基础数据以及价格数据下载交易日历和基础数据查看股票和指数的基础数据下载沪市股票数据从本地获取股价数据生成K线图 数据类型的查找定期下载数据到本地回顾总结 qteasy教程2 - 获取并…

Swift Combine 网络受限时从备用 URL 请求数据 从入门到精通十四

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

【python】网络爬虫与信息提取--Beautiful Soup库

Beautiful Soup网站&#xff1a;https://www.crummy.com/software/BeautifulSoup/ 作用&#xff1a;它能够对HTML.xml格式进行解析&#xff0c;并且提取其中的相关信息。它可以对我们提供的任何格式进行相关的爬取&#xff0c;并且可以进行树形解析。 使用原理&#xff1a;它能…

红队打靶练习:Alfa:1

下载连接点击此处即可&#xff01; 目录 信息收集 1、arp 2、nmap 3、gobuster WEB web信息收集 FTP登录 smaba服务 crunch密码生成 提权 系统信息收集 权限提升 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, …