西南交通大学【算法分析与设计实验1】

实验1.4 有向图拓扑排序

实验目的

(1)掌握算法的自然语言描述法,流程图绘制方法以及伪代码描述方法。

(2)理解算法的执行过程。

(3)掌握算法的编程实现方法、调试方法及测试方法。

实验任务

按照实验教程上图1-6的伪代码,实现基于深度优先(DFS)的有向图拓扑排序算法。具体要求如下:

(1)阅读并理解该伪代码。

(2)根据测试用例,分析该算法的执行过程。

(3)用C++语言实现该算法,并针对测试用例,将程序运行结果和手工分析结果进行对比验证。

(4)撰写实验报告,实验报告内容包括实验目的、实验任务、实验环境、实验步骤、实验结果和实验总结等部分。

实验步骤及结果

 实验预习

根据测试用例分析算法的执行过程

(1)测试用例1

从顶点1开始,按照字典序进行DFS,给出每一步TS-Visit的中间结果。

初始状态

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

False

False

False

Visited

False

False

False

False

False

δ

0

0

0

0

0

第1次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

False

False

False

Visited

False

False

False

False

False

δ

0

0

0

0

0

第2次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

False

False

False

False

Visited

False

False

False

False

False

δ

0

0

0

0

0

第3次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

False

False

Visited

False

False

False

False

False

δ

0

0

0

0

0

第4次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

True

False

Visited

False

False

False

False

False

δ

0

0

0

0

0

返回第4次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

True

False

Visited

False

False

False

False

True

δ

0

0

0

0

5

返回第3次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

False

False

Visited

False

False

False

True

True

δ

0

0

0

4

5

第5次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

False

False

Visited

False

False

False

True

True

δ

0

0

0

4

5

返回第5次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

True

False

False

False

Visited

False

False

False

True

True

δ

0

0

0

4

5

返回第2次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

True

False

False

False

False

Visited

False

True

False

True

True

δ

0

3

0

4

5

返回第1次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

False

False

False

Visited

True

True

False

True

True

δ

2

3

0

4

5

第6次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

False

False

False

Visited

True

True

False

True

True

δ

2

3

0

4

5

第7次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

True

False

False

Visited

True

True

False

True

True

δ

2

3

0

4

5

返回第7次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

True

False

False

Visited

True

True

False

True

True

δ

2

3

0

4

5

返回第6次调用TS-Visit

顶点1

顶点2

顶点3

顶点4

顶点5

Stacked

False

False

False

False

False

Visited

True

True

True

True

True

δ

2

3

1

4

5

最终的拓扑排序结果:

3 1 2 4 5

(2)测试用例2

最终的拓扑排序结果:

6 1 4 3 5 2

伪代码中 if v is marked stacked 如果为真,表示什么意思?

答:正常程序不会出现if v is marked stacked为真的情况,伪代码中 if v is marked stacked 如果为真表示此图中出现了环。

用C/C++语言实现该算法

算法要求的输入格式为:

第一行是两个整数 n m,分别表示图的顶点数和边数,顶点从 1 到 n编号;其后有 m 行,每行两个整数,分别表示每条有向边的起始顶点和结束顶点。

例:测试用例 1 对应的输入如下:

5 5

1 2

2 4

2 5

3 4

4 5

算法要求的输出格式为:

按照拓扑排序排好的顶点编号,编号之间用一个空格分割。

源代码:

#include <iostream>
#define MAX_VERTEX_N 20 // 最大节点数+1
using namespace std;
// 判断是否有环
int flag = 0;
// 图的类型
typedef enum
{
    DG, // 有向图
    DN, // 有向网
    UDG, // 无向图
    UDN // 无向网
}GraphKind;
// 边节点
typedef struct ArcNode
{
    int adjvex; // 数据域
    struct ArcNode *nextarc; // 下一个邻接点
}ArcNode;
// 节点
typedef struct
{
    int data; // 数据域
    ArcNode *firstarc; // 第一个邻接点
}VNode, AdjList[MAX_VERTEX_N];
// 图
typedef struct
{
    AdjList vexs; // 节点数组
    int vex_num; // 节点数
    int arc_num; // 弧数
    GraphKind kind; // 图类型
} ALGraph;
// 输入数据创建邻接表
void CreateUDN(ALGraph &G)
{
    // 节点个数 弧个数
    int v_num, a_num;
    cin>>v_num>>a_num;
    G.vex_num = v_num;
    G.arc_num = a_num;
    // 初始化图的邻接表的点数组
    for(int i = 1;i <= v_num;++i){
        G.vexs[i].data = i;
        G.vexs[i].firstarc = NULL;
    }
    for(int i = 0;i < a_num;++i){
        // 起始节点 终止节点
        int v1, v2;
        // 定位点邻接的最后一个点节点
        ArcNode *end;
        cin>>v1>>v2;
        ArcNode *temp = new ArcNode;
        temp->adjvex = v2;
        temp->nextarc = NULL;
        end = G.vexs[v1].firstarc;
        // 如果v1还没有邻接点
        if(!end){
            G.vexs[v1].firstarc = temp;
        }else{// 在最后继续邻接
            while (end->nextarc)
            {
                end = end->nextarc;
            }
            end->nextarc = temp;
        }
    }
}
// 访问各个节点
void visit(ALGraph G, int index, int *judge, int *res, int &i){
    // 如果是状态1,则返回
    if(judge[index] == 1){
        flag = 1;
        return;
    }
    // 如果是状态0即未访问
    if(judge[index] == 0){
        judge[index] = 1;
        ArcNode *temp = G.vexs[index].firstarc;
        // 深度搜索
        while (temp)
        {
            visit(G, temp->adjvex, judge, res, i);
            temp = temp->nextarc;
        }
        // 改为已访问状态
        judge[index] = 2;
        // 将节点下标存储在结果数组res中
        res[i] = index;
        i--;
    }
}
// 拓扑排序
void TopologicalSort(ALGraph G){
    int i = G.vex_num;
    int *judge = new int[G.vex_num+1];
    int *res = new int[G.vex_num+1];
    // 初始化判断数组
    for(int j = 1;j <= G.vex_num;++j){
        judge[j] = 0;
    }
    // 从一个未访问节点出发
    for(int j = 1;j <= G.vex_num;++j){
        if(judge[j] == 0){
            visit(G, j, judge, res, i);
        }
    }
    // 输出结果
    if(flag){
        cout<<"此图有环,没有拓扑排序"<<endl;
    }else{
        for(int j = 1;j <= G.vex_num;++j){
            cout<<G.vexs[res[j]].data<<" ";
        }
    }
    delete judge;
    delete res;
}
// 释放创建图时动态申请的内存
void des(ALGraph &G)
{
    for (int i = 1; i <= G.vex_num; ++i)
    {
        ArcNode *p = G.vexs[i].firstarc;
        ArcNode *q = NULL;
        while (p)
        {
            q = p->nextarc;
            delete p;
            p = q;
        }
    }
}
int main(void)
{
    ALGraph G;
    // 创建图
    CreateUDN(G);
    // 进行拓扑排序
    TopologicalSort(G);
    cout<<endl;
    // 释放内存
    des(G);
    system("pause");
    return 0;
}

上机实验

测试用例1

测试用例输入:

9 9

1 2

1 8

2 3

2 8

3 4

5 3

5 6

6 4

7 8

测试用例示意图:

手工计算结果:

9 7 5 6 1 2 8 3 4

程序运行结果:

测试用例2

测试用例输入:

10 12

1 3

1 6

2 4

3 4

3 5

4 7

5 8

6 5

6 8

7 9

8 9

9 10

测试用例示意图:

手工计算结果:

2 1 6 3 5 8 4 7 9 10

程序运行结果:

单步调试截图

实验总结

通过本次实验,掌握了如何去阅读和理解算法的伪代码表示方法以及基于算法的伪代码实现算法程序。熟悉了程序的调试过程,并学会了如何分析算法的执行过程以及验证算法及程序的正确性。为后续算法的学习以及应用奠定了一定的基础。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AcWing 1256:扩展二叉树

【题目来源】https://www.acwing.com/problem/content/1258/【题目描述】 由于先序、中序和后序序列中的任一个都不能唯一确定一棵二叉树&#xff0c;所以对二叉树做如下处理&#xff0c;将二叉树的空结点用 补齐&#xff0c;如图所示。 我们把这样处理后的二叉树称为原二叉树…

智谱AI: ChatGLM API的使用

一、获取API 1、打开网址&#xff1a;智谱AI开放平台 注册账号登录 2、登录&#xff0c;查看API key (注册后赠送100万token&#xff0c;实名认证后多赠送400万, 有效期一个) 二、安装及调用 安装质谱SDK pip install zhipuai调用方式 流式调用 from zhipuai import ZhipuA…

Vulkan学习——渲染3D模型

摘要&#xff1a;本文简要描述了Vulkan渲染一个3D模型需要做的事情&#xff0c;不会对太细节的内容进行深究。   关键字&#xff1a;Vulkan,Render,3D 源码 1 简介 1.1 Vulkan简介 Vulkan是一个低开销、跨平台的二维、三维图形与计算的应用程序接口&#xff08;API&#x…

鸿蒙开发Ability Kit(程序访问控制):【使用粘贴控件】

使用粘贴控件 粘贴控件是一种特殊的系统安全控件&#xff0c;它允许应用在用户的授权下无提示地读取剪贴板数据。 在应用集成粘贴控件后&#xff0c;用户点击该控件&#xff0c;应用读取剪贴板数据时不会弹窗提示。可以用于任何应用需要读取剪贴板的场景&#xff0c;避免弹窗…

基于MATLAB对线阵天线进行泰勒加权

相控阵天线——基于MATLAB对线阵进行泰勒加权 目录 前言 一、泰勒综合 二、单元间距的改变对泰勒阵列方向图的影响 三、单元数的改变对泰勒阵列激励分布的影响 四、副瓣电平SLL对泰勒阵列激励幅度的影响 五、副瓣电平SLL对泰勒阵列方向图的影响 六、泰勒阵列和切比雪夫阵…

Qt Creator13配置Android开发环境

QT Creator13是目前&#xff08;2024年&#xff09;最新版本&#xff0c;配置Android开发环境有一些不一样&#xff0c;走了一些弯路&#xff0c;记录如下。 1、安装JDK和SDK 下载安装JDK和SDK&#xff0c;建议安装在无空格和中文字符的目录下。 具体安装步骤不再赘述&#…

Python基础003

Python流程控制基础 1.条件语句 内置函数input a input("请输入一段内容&#xff1a;") print(a) print(type(a))代码执行的时候遇到input函数&#xff0c;就会等键盘输入结果&#xff0c;已回车为结束标志&#xff0c;也就时说输入回车后代码才会执行 2.顺序执行…

看完这篇文章你就知道什么是未来软件开发的方向了!即生成式AI在软件开发领域的革新=CodeFlying

从最早的UGC&#xff08;用户生成内容&#xff09;到PGC&#xff08;专业生成内容&#xff09;再到AIGC&#xff08;人工智能生成内容&#xff09;体现了web1.0→web2.0→web3.0的发展历程。 毫无疑问UGC已经成为了当前拥有群体数量最大的内容生产方式。 同时随着人工智能技术…

leetcode每日一练:链表OJ题

链表经典算法OJ题 1.1 移除链表元素 题目要求&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&a…

Kotlin扩展函数(also apply run let)和with函数

also apply run let with的使用例子 private fun testOperator() {/*** also*/val person Person("ZhangSan", 18)person.also {// 通常仅仅打印使用, 也可以通过it修改it.name "ZhangSan1"println("also inner name: " it.name)}println(&qu…

如何理解MySql的MVCC机制

MVCC是什么 MySQL的MVCC机制&#xff0c;全称为多版本并发控制&#xff08;Multi-VersionConcurrency Control&#xff09;&#xff0c;是一种提高数据库并发性能的技术。MVCC的主要目的是在保证数据一致性的同时&#xff0c;提高数据库的并发性能。 它通过为每个读操作创建数…

lower()方法——大写字母转换为小写字母

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 lower()方法用于将字符串中的大写字母转换为小写字母。如果字符串中没有需要被转换的字符&#xff0c;则将原字符串返回&#xff1b;否则将…

Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件

章节内容 上一节完成&#xff1a; HDFS的简介内容HDFS基础原理HDFS读文件流程HDFS写文件流程 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&#xff0c;但是没留下…

RK3568平台(USB篇)USB HID设备

一.USB HID设备简介 USB HID设备主要用于和计算机进行交互通信&#xff0c;典型的USB HID类设备包括USB键盘、USB鼠标、USB游戏手柄等等&#xff0c;这些都是日常生活中常见的设备。以USB接口的鼠标为例&#xff0c;打开计算机的“设备管理器”&#xff0c;可以在“鼠标和其他…

Milvus【部署 01】向量数据库Milvus在Linux环境下的在线+离线安装

向量数据库Milvus在Linux环境下的在线离线安装 1.千问简介2.在线安装2.离线安装 1.千问简介 Milvus 是一款专为处理高维向量数据设计的开源云原生数据库&#xff0c;旨在满足海量向量数据的实时召回需求。它由 Zilliz 公司开发并维护&#xff0c;基于Apache许可证2.0版本发布。…

Microsoft SQL Server 2019安装和设置用户密码

1、免费下载两个安装包 SQL2019-SSEI-Dev 地址:https://www.microsoft.com/en-us/sql-server/sql-server-downloads SSMS-Setup-CHS 地址:https://aka.ms/ssmsfullsetup 安装具体不在阐述了&#xff0c;可以参考我这篇文章&#xff1a;SQL Server 2019安装详细教程 2、以W…

llm-universe | 五. 系统评估与优化

系统评估与优化 一.LLM应用评估思路1.人工评估准则一 量化评估准则二 多维评估 2.自动评估方法一. 构造客观题方法二. 计算答案相似度 3.使用大模型评估4.混合评估 二.评估并优化生成部分1. 提升直观回答质量2.标明知识来源&#xff0c;提高可信度3. 构造思维链4.增加一个指令解…

springboot学习,如何用redission实现分布式锁

目录 一、springboot框架介绍二、redission是什么三、什么是分布式锁四、如何用redission实现分布式锁 一、springboot框架介绍 Spring Boot是一个开源的Java框架&#xff0c;由Pivotal团队&#xff08;现为VMware的一部分&#xff09;于2013年推出。它旨在简化Spring应用程序…

详解C语言分支与循环语句

分支语句 if elseswitch 循环语句 whilefordo while goto语句 文章目录 1.什么是语句2.分支语句&#xff08;选择结构&#xff09;2.1 if语句2.1.1 悬空else2.1.3 练习 2.2 switch语句2.2.1 在switch语句中的break2.2.2 default子句 3.循环语句3.1 while循环3.1.1 while语句中…

2024广州智能音箱展|广州蓝牙耳机展

2024广州智能音箱展|广州蓝牙耳机展 时间&#xff1a;2024年11月29日-12月1日 地点&#xff1a;广州琶洲保利世贸博览馆 【展会简介】 中国是全球最大的音频产品制造基地和消费市场&#xff0c;随着国内外互联网巨头纷纷瞄准音频行业并投入巨资布局AI产品矩阵&#xff0c;音…