《数据结构》课程设计 —— 栈的实现(C++)

目录

栈的实现

项目获取

具体实现文件解析

pubuse.h头文件

 SqStackDef.h文件

SqStackAlgo.h 文件 

SqStackUse.cpp 文件

结语


栈的实现

文件名功能
pubuse.h提供了常用的预处理宏、类型别名和标准库引用,如状态值和控制操作。
SqStackAlgo.h定义了Stack类,包括栈操作函数如初始化、插入/移除元素,以及用于表达式处理的运算符优先级和转后缀表达式等算法。
SqStackDef.h描述栈数据结构的定义,包括Stack类的组成部分(栈底指针、栈顶指针和大小等)。
SqStackUse.cpp用户界面接口,包含基本栈操作(创建、显示、操作元素)的函数实现,以及解析和计算数学表达式的功能。

程序整体功能:SqStackUse.cpp 实现了一个命令行界面,用户可以通过栈操作来管理字符数据,还能够解析和计算基于中缀表达式的数学计算。其他文件(pubuse.hSqStackAlgo.h, 和 SqStackDef.h)提供了核心数据结构和相关函数的支持。

这些文件构成了一个C++项目,由pubuse.h提供预处理宏与库支持,SqStackAlgo.h定义Stack类及其算法,SqStackDef.h定义数据结构,而SqStackUse.cpp则是用户驱动的栈操作和表达式处理程序实现。

项目获取

【免费】学生课程实验,C++数据结构实验,栈的实现,vs2022完整项目,包含完整代码,开箱即用资源-CSDN文库icon-default.png?t=N7T8https://download.csdn.net/download/btaworld/89291963?spm=1001.2101.3001.9500

所有代码已经上传到CSDN,通过资源绑定功能已经绑定本篇博客,有需要请自取,完整的VS2022项目,运行“数据结构-栈的实现.sln”即可在vs2022中打开(一般来说,版本无限制)

在我上传时,设置了0积分,可以免费获取,但不保证后续积分要求会不会变化(但放心,不会变成付费或会员专享资源),不过,还请尽快保存! 

具体实现文件解析

pubuse.h头文件

这段代码是pubuse.h头文件,主要包括以下内容:

  1. 定义预处理器宏常量(如 TRUE/FALSE/OK/ERROR),用于简化状态值表示。
  2. 使用 C++ 标准类型别名:Status 和 Boolean,分别用于存储状态和布尔值,方便在函数返回类型和使用上。
  3. #pragma once 特性,确保此头文件只被包含一次,避免多次定义。

文件中包含了 C++ 中常用的一些头文件,比如 <string><iostream><cstdlib><conio.h> 等,它们分别提供了字符串处理、输入输出、内存管理、控制台输入输出等基础功能。

整体来看,这个文件旨在为后续的代码提供一些基本的类型定义、预处理变量以及必要的库引用,它可能是一个公共模块或者基础工具类的定义部分。

#include<string> 
#include<ctype.h> 
#include<malloc.h> /* malloc()等*/ 
#include<limits.h> /* INT_MAX 等*/ 
#include<stdio.h> /* EOF(=^Z 或F6),NULL */ 
#include<iostream>
#include<stdlib.h> /* atoi() */ 
#include<io.h> /* eof() */ 
#include<math.h>/* floor(),ceil(),abs() */ 
#include<process.h> /* exit() */ 
#include"conio.h" 
#include <sstream>

using namespace std;

/* 函数结果状态代码*/
#define TRUE 1 
#define FALSE 0 
#define OK 1 
#define ERROR 0 
#define INFEASIBLE -1 
//#define OVERFLOW -2 因为在math. h 中已定义OVERFLOW 的值为3,故去掉此行
typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/
typedef int Boolean; /* Boolean 是布尔类型,其值是TRUE 或FALSE */
#pragma once

 SqStackDef.h文件

这个SqStackDef.h文件是用于定义一个名为SqStack的数据结构,它表示一个栈(stack)的实现。栈是一种线性数据结构,遵循后进先出(LIFO,Last In, First Out)原则。

  • SElemType 是一个结构体别名,它包含两个元素:一个字符c和一个双精度浮点数num,这代表栈中的通用元素类型。
  • SqStack 结构体包含了以下三个成员:
  • base:指向栈底元素的指针。
  • top:指向栈顶元素的指针。
  • stacksize:表示栈的当前大小(最多可以存储的元素数量),使用预定义的最大值MAXSIZE(这里是100)。

通过这个头文件,其他代码可以包含SqStack类型并操作它们,比如创建、删除元素和检查栈是否为空等。pubuse.h可能是另一个包含了公共函数声明的头文件,但在这个代码片段中没有直接用到。

#include"pubuse.h"
#define MAXSIZE 100
typedef struct
{
	char c;
	double num;
}SElemType;
typedef struct
{
	SElemType* base;
	SElemType* top;
	int stacksize;
}SqStack;

SqStackAlgo.h 文件 

SqStackAlgo.h 是一个 C++ 文件,定义了一个名为 SqStack 的自定义栈数据结构及其操作方法(如初始化、压入元素、弹出元素等)。其中还包括了辅助功能:

  1. 定义了状态枚举 Status,用于表示操作结果。
  2. 验证栈是否为空(StackEmpty)和检查栈顶是否有元素(IsEmpty)的函数。
  3. 计算栈的长度(StackLength)。
  4. 展示栈中所有元素的操作(ShowAll)。
  5. 一个函数 Priority_ss 来确定运算符的优先级。
  6. change_ss 函数负责把中缀表达式转换为后缀(也称逆波兰)表达式,涉及到符号处理和括号匹配。
  7. js_new_ss 函数接受一个后缀表达式,并计算其对应的数值结果。

整体来看,这个文件提供了一套完整的栈数据结构和算法来支持表达式的处理。

#include"SqStackDef.h"

//初始化
Status InitStack(SqStack& S) {
	S.base = new SElemType[MAXSIZE];
	if (!S.base) exit(OVERFLOW);
	S.top = S.base;
	S.stacksize = MAXSIZE;
	return OK;
}

//入栈
Status Push(SqStack& S, SElemType e) {
	if (S.top - S.base == S.stacksize) return ERROR;
	*S.top++ = e;
	return OK;
}

//出栈
Status Pop(SqStack& S, SElemType &e) {
	if (S.top == S.base) return ERROR;
	e = *--S.top;
	return OK;
}

//取栈顶元素
SElemType GetTop(SqStack S) {
	if (S.top != S.base) return *(S.top - 1);
}

//销毁栈
Status DestroyStack(SqStack &S) {
	if(S.base) {
		delete S.base;
		S.stacksize = 0;
		S.base = S.top = NULL;
	}
	return OK;
}

//置空栈
Status StackEmpty(SqStack& S) {
	S.top = S.base;
	return OK;
}

//判是否空栈
bool IsEmpty(SqStack S) {
	return S.base == S.top;
}

//求栈的长度
int StackLength(SqStack S) {
	return S.top - S.base;
}

//栈遍历
Status ShowAll(SqStack S) {
	SElemType* p = S.base;
	while (p != S.top)
	{
		cout << p->c << endl;
		p++;
	}
	return OK;
}

// 获取运算符的优先级
int Priority_ss(char op) {
	if (op == '*' || op == '/') return 2;
	else if (op == '+' || op == '-') return 1;
	else return 0; // '('优先级最低
}

// 将中缀表达式转换为后缀表达式
string change_ss(string ss) {
	SqStack S; // 用于存储运算符的栈
	SElemType e1; //弹出无用栈顶元素,过渡
	InitStack(S);
	string new_ss = ""; //后缀表达式

	istringstream iss(ss);
	string s1;
	while (iss >> s1) {
		if (isdigit(s1[0])) {
			// 如果是数字,将数添加到后缀表达式中
			new_ss += s1;
			new_ss += " ";
		}
		else if (s1 == "(") {
			// 如果是'(',直接入栈
			SElemType e;
			e.c = '(';
			Push(S, e);
		}
		else if (s1 == ")") {
			// 如果是')',将运算符栈中的运算符弹出并添加到后缀表达式中,直到遇到'('
			while (!IsEmpty(S) && GetTop(S).c != '(') {
				new_ss += GetTop(S).c;
				new_ss += " ";
				Pop(S, e1);
			}
			Pop(S, e1); // 弹出'('
		}
		else if (s1 == "+" || s1 == "-" || s1 == "*" || s1 == "/") {
			// 如果是运算符,弹出优先级大于等于当前运算符的运算符,添加到后缀表达式中,并将当前运算符入栈
			while (!IsEmpty(S) && Priority_ss(GetTop(S).c) >= Priority_ss(s1[0])) {
				new_ss += GetTop(S).c;
				new_ss += " ";
				Pop(S, e1);
			}
			SElemType e;
			e.c = s1[0];
			Push(S, e);
		}
		else
		{
			return "false";
		}
	}
……完整代码,请下载本博客绑定的资源(请见谅)

SqStackUse.cpp 文件

SqStackUse.cpp 文件是一个C++程序,实现了栈(Stack)的一些基本操作。它包含了以下几个功能:

  1. ShowMenu():显示菜单,列出栈的基本操作选项。
  2. ExitEnter(): 清屏并暂停程序执行。
  3. main()
    • 初始化栈(case 1):调用名为 InitStack 的函数初始化栈。
    • 检查栈是否已空并破坏(case 2):分别对应销毁栈的操作与检查。
    • 判断栈是否为空(case 3)、是否只包含一个元素(case 4),以及获取栈顶元素(case 6)。
    • 执行push(入栈)操作(case 7),接收用户输入的字符并将它们添加到栈中。
    • 弹出并打印栈顶元素(case 8)。
    • 显示全部栈元素(case 9)。
    • 解析并计算数学表达式(case 10),调用 change_ss 和 js_new_ss 函数执行计算。
    • 主循环控制,当选择等于0时退出。

这个程序提供了一个用户接口,用于操作一个简单的字符栈数据结构,同时包含了一个字符串数学运算处理功能。

#include"SqStackAlgo.h"

void ShowMenu() {
    cout << "========= 栈的实现及应用 =========" << endl;
    cout << "1. 初始化(使用以下功能时,务必先初始化,除了算术运算)" << endl;
    cout << "2. 销毁栈" << endl;
    cout << "3. 置空栈" << endl;
    cout << "4. 判断是否空栈" << endl;
    cout << "5. 求栈的长度" << endl;
    cout << "6. 取栈顶元素" << endl;
    cout << "7. 入栈" << endl;
    cout << "8. 出栈" << endl;
    cout << "9. 栈遍历" << endl;
    cout << "10. 算术运算" << endl;
    cout << "0. 退出" << endl;
    cout << "请输入你的选择:";
}
void ExitEnter() {
    cout << "-------------------------------" << endl;
    system("pause");
    system("cls");
}

int main() {
    SqStack S;
    SElemType e;
    int numF = 12; //菜单选项数量
    int choice;
    do {
        ShowMenu();
        cin >> choice;
        while (choice < 0 || choice>numF || cin.fail())
        {
            system("cls");
            cin.clear();
            cin.ignore();
            ShowMenu();
            cin >> choice;
        }

        switch (choice) {
        case 1: {
            // 初始化
            system("cls");
            if (InitStack(S)) cout << "初始化成功" << endl;
            else cout << "初始化失败" << endl;
            ExitEnter();
            break;
        }
        case 2: {
            // 销毁栈
            system("cls");
            if (DestroyStack(S)) cout << "销毁栈成功" << endl;
            else cout << "销毁栈失败" << endl;
            ExitEnter();
            break;
        }
        case 3: {
            // 置空栈
            system("cls");
            if (StackEmpty(S)) cout << "置空栈成功" << endl;
            else cout << "置空栈失败" << endl;
            ExitEnter();
            break;
        }
        case 4: {
            // 判是否空栈
            system("cls");
            if (IsEmpty(S)) cout << "是空栈" << endl;
            else cout << "不是空栈" << endl;
            ExitEnter();
            break;
        }
        case 5: {
            // 求栈的长度
            system("cls");
            int i = StackLength(S);
            cout << "栈的长度为:" << i << endl;
            ExitEnter();
            break;
        }
        case 6: {
            // 取栈顶元素
            system("cls");
            if (!IsEmpty(S)) {
                e = GetTop(S);
                cout << "栈顶元素为:" << e.c << endl;
            }
            else
            {
                cout << "取取栈顶元素失败" << endl;
            }
            
            ExitEnter();
            break;
        }
        case 7: {
            // 入栈
            system("cls");
            cout << "入栈,输入char字符,回车入栈(输入n再回车退出)" << endl;
            char in;
            while (TRUE)
            {
                cout << "开始输入:";
                cin >> in;
                while (cin.fail())
                {
                    cin.ignore();
                    cin.clear();
                    cout << "输入有误,重新输入:";
                    cin >> in;
                }
                if (in == 'n') break;
                e.c = in;
                Push(S, e);
            }
            ExitEnter();
            break;
        }
        case 8: {
            // 出栈
            system("cls");
            if (Pop(S, e) && !IsEmpty(S)) {
                cout << "出栈成功" << endl;
                cout << "出栈元素为:" << e.c << endl;
            }
            else cout << "栈空,出栈失败" << endl;
            ExitEnter();
            break;
        }
        case 9: {
            // 栈遍历
            system("cls");
            if (ShowAll(S) && !IsEmpty(S))cout << "\n栈遍历成功" << endl;
            else cout << "栈遍历失败" << endl;
            ExitEnter();
            break;
        }
        case 10: {
            // 算术运算
            system("cls");
            cin.ignore();
            
            string ss;
            cout << "输入的算术表达式,数字和运算符用空格隔开,比如:100 + 2.5 - ( 7 - 1 * 2 ) / 2" << endl;
            cout << "请输入(不支持负数):";
            getline(cin, ss);

            // 将中缀表达式转换为后缀表达式
            string new_ss = change_ss(ss);
            if (new_ss != "false") {
                cout << "后缀表达式:" << new_ss << endl;
                double result = js_new_ss(new_ss);
                cout << "结果:" << result << endl;
            }
            else
            {
                cout << "算式输入有误" << endl;
            }

            ExitEnter();
            break;
        }
        case 0: {
            cout << "-------------------------------" << endl;
            cout << "感谢使用,再见!" << endl;
            break;
        }
        default:
            system("cls");
            cout << "输入无效,请重新选择!" << endl;
            break;
        }
    } while (choice != 0);
    return 0;
}

结语

希望你能通过本篇博客,更好理解数据结构——栈。

最后,使用愉快!

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值