实验报告——栈、队列与递归

集美大学课程实验报告-实验3:栈、队列与递归

项目名称 内容
课程名称 数据结构
班级 网安2512
学号 202521336035
实验项目名称 栈、队列与递归
上机实践日期 2026.04.03
上机实践时间 2学时

一、目的(本次实验所涉及并要求掌握的知识点)

  • 掌握C++STL中string字符串的常用操作方法。
  • 学习使用stack与queue的入栈、出栈、入队、出队、判空等基本操作。
  • 理解栈在符号匹配、数字转换等场景的应用。
  • 掌握递归函数的编写规范,理解函数调用与系统栈的关系。
  • 理解队列在排队、资源分配等实际问题中的应用。

二、实验内容与设计思想

题目1:栈的应用

函数相关伪代码

符号配对函数ismatched(str)
{
    创建空栈stack<char>left
    getline(cin,str)读取字符串
    for(char ch:str)遍历字符
        if(ch为左符号)
            stack.push(ch)入栈
        else if(ch为右符号)
            if(判断栈是否为空)
                return false
            top=stack.pop()取出栈顶元素
            stack.pop()出栈
            if(top与ch无法配对)
                return false
    return true

函数代码

bool ismatched(const string &str){
    string str;
    getline(cin,str);
    stack<char>left;
    for(char ch:str){
        if(ch=='('||ch=='{'||ch=='['){
            left.push(ch);
        }else if(ch==')'||ch=='}'||ch==']'){
            if(left.empty()){
                return false;
            }
            char top=left.top();
            if((ch==')'&&top=='(')||(ch==']'&&top=='[')||(ch=='}'&&top=='{')){
                left.pop();
            }else{
                return false;
            }
        }
    }
    return true;
}

题目2:递归程序编写

函数相关伪代码

确定最大整数函数maxnum(f)
    if(f==nullptr)
        return INT_MIN 空节点,返回整形最小值
    max=maxnum(f->next) 递归:保存子链表最大值
    return f->data>max?f->data:max 比较更新最大值

确定节点个数函数count(f)
    if(f==nullptr)
        return 0 空节点,节点个数为0
    return 1+count(f->next) 递归:当前节点+后续节点个数

求节点数据总和函数sumnum(f)
    if(f==nullptr)
        return 0 空节点,总和为0
    return f->data+sumnum(p->next) 递归:当前节点数据+后续节点数据

求平均值函数average(f)
    datacount=count(f) 递归得到节点个数
    if(datacount==0) 判断是否存在平均值
        cout<<"链表为空,平均值不存在!"<<endl
        return 0
    int sum=sumnum(f) 递归得到数据总和
    return (double)sum/datacount 返回平均值

函数代码

int maxnum(LinkList f) //确定最大值
{
    if (f == nullptr) {
        return INT_MIN;
    }
    int max = maxnum(f->next);
    return f->data > max ? f->data : max;
}
int count(LinkList f) //确定节点个数
{
    if (f == nullptr) {
        return 0;
    }
    return 1 + count(f->next);
}
int sumnum(LinkList f) //求数据总和
{
    if (f == nullptr) {
        return 0;
    }
    return f->data + sumnum(f->next);
}
double average(LinkList f) //求平均值
{
    int datacount = count(f);
    if (datacount == 0) {
        cout << "链表为空,平均值不存在" << endl;
        return 0;
    }
    int sum = sumnum(f);
    return (double)sum / datacount;
}

题目3:队列的应用

函数相关伪代码

求队列长度函数QueueLen(Q)
    return(Q->rear-Q->front+MAXSIZE)%MAXSIZE 返回队列长度

入队操作函数EnQueue(&Q,e)
    if((Q->rear+1)%MAXSIZE==Q->front) 判断是否队满
        return ERROR
    Q->data[Q->rear]=e 将元素e放入队中
    Q->rear=(Q->rear+1)%MAXSIZE 队尾指针后移
    return OK

判断队列是否为空函数QueueEmpty(&Q)
    return Q->rear==Q->front?OK:ERROR 队头指针、队尾指针指向位置相同时队列为空

出队操作函数DeQueue(&Q,&e)
    if(QueueEmpty(Q)==OK) 调用函数判断队列是否为空
        return ERROR
    e=Q->data[Q->front] 取出队头元素
    Q->front=(Q->front+1)%MAXSIZE 队头指针后移
    return OK

配对舞伴函数DancePartner(dancer[],num)
    for(int i=0;i<num;++i) 遍历所有舞者人并按性别入队
        if(dancer[i].sex=='F') 判断性别是否为女性
            EnQueue(Fdancers,dancer[i]) 调用函数入队
        else if(dancer[i].sex=='M') 判断性别是否为男性
            EnQueue(Mdancers,dancer[i]) 调用函数入队
    female,male 定义变量存放出队的人
    while(QueueEmpty(Fdancers)!=OK&&QueueEmpty(Mdancers)!=OK) 调用函数判断男生,女生队列是否为空
        DeQueue(Fdancers,female) 女生出队
        DeQueue(Mdancers,male)  男生出队
        cout<<female.name<<" "<<male.name<<endl 打印出成功配对的舞伴

函数代码

int QueueLen(SqQueue Q)//队列长度
{
    return (Q->rear - Q->front + MAXQSIZE) % MAXQSIZE;
}
int EnQueue(SqQueue &Q, Person e)//加入队列
{
    if ((Q->rear + 1) % MAXQSIZE == Q->front) {
        return ERROR;
    }
    Q->data[Q->rear] = e;
    Q->rear = (Q->rear + 1) % MAXQSIZE;
    return OK;
}
int QueueEmpty(SqQueue &Q)//队列是否为空 
{
    return Q->rear == Q->front ? OK : ERROR;
}
int DeQueue(SqQueue &Q, Person &e)//出队列 
{
    if (QueueEmpty(Q) == OK) {
        return ERROR;
    }
    e = Q->data[Q->front];
    Q->front = (Q->front + 1) % MAXQSIZE;
    return OK;
}
void DancePartner(Person dancer[], int num)//配对舞伴
{
    for (int i = 0; i < num; ++i) {
        if (dancer[i].sex == 'F') {
            EnQueue(Fdancers, dancer[i]);
        }else if (dancer[i].sex=='M') {
            EnQueue(Mdancers, dancer[i]);
        }
    }
    Person female, male;
    while (QueueEmpty(Fdancers) != OK && QueueEmpty(Mdancers) != OK) {
        DeQueue(Fdancers, female);
        DeQueue(Mdancers, male);
        cout << female.name << " " << male.name << endl;
    }
}

三、实验使用环境(本次实验所使用的平台和相关软件)

  • 操作系统:Windows 11专业版
  • 编程语言:C++
  • 开发工具Visual Studio 2026
  • 编译器:vs2026默认编译器、g++

四、实验步骤和调试过程(实验步骤、测试数据设计、测试结果分析)

题目1:符号配对

本机运行截图
image

image

PTA提交截图
image

题目2:递归程序编写

本机运行截图
image

题目3:舞伴问题

本机运行截图
image

PTA提交截图
image


五、实验小结(实验中遇到的问题及解决过程、实验体会和收获)

遇到的问题及解决方法:

  1. 问题:符号匹配时未判断栈空直接取栈顶,导致崩溃。
    • 解决方法:先判断栈空,如果为空则直接返回false不匹配。
  2. 问题:循环队列的判满判空操作错误,导致出错。
    • 解决方法:通过查阅课本熟记判满判空的核心规则,修正原队列操作。

实验体会和收获:

  • 熟练掌握了string字符串的常用操作方法,stack与queue的入栈、出栈、入队、出队、判空等基本操作。
  • 掌握了栈的典型应用——符号匹配,加深了对栈“先进后出”特点的理解。
  • 学习了递归函数的编写方法,理解递归了调用与系统栈的关系,能用递归实现求最值、求和、求平均值等基础。
  • 掌握了队列的典型应用——舞伴问题,加深了对队列“先进先出”特点的理解。
  • 进一步掌握了伪代码的编写规范,算法逻辑更加清晰。

六、附件(参考文献和相关资料)

  1. C++ Primer
  2. 实验3-栈与队列
posted @ 2026-04-04 15:46  xin_fffffly  阅读(4)  评论(0)    收藏  举报