GDPU 数据结构 天码行空12

news2024/11/20 6:35:04

文章目录

  • 数据结构实验十二 图的遍历及应用
    • 一、【实验目的】
    • 二、【实验内容】
    • 三、实验源代码
      • 🍻 CPP
      • 🍻 C

数据结构实验十二 图的遍历及应用

一、【实验目的】

1、 理解图的存储结构与基本操作;
2、熟悉图的深度度优先遍历和广度优先遍历算法
3、掌握图的单源最短路径算法

二、【实验内容】

1.根据下图邻接矩阵,编程实现该图的深度与广度优先遍历算法,输出遍历序列。
在这里插入图片描述

2.单源节点最短路径问题
问题描述:求从有向图的某一结点出发到其余各结点的最短路径。
基本要求:
(1)有向图采用邻接矩阵表示。
(2)单源节点最短路径问题采用Dijkstra算法。
(3)输出有向图中从源结点T到其余各结点的最短路径和最短路径值。

三、实验源代码

🍻 CPP

#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;

const int N = 6;
const int M = N*N;
const int INF = 0x3f3f3f3f;
const int 无边 = -1;

int g[N][N]; //grap数组记录邻接矩阵【-1 表示不可达】
bool vs[N];//visted数组记录结点是否已经被访问过

void add(int a, int b, int c)
{
	// 邻接矩阵加边
	g[a][b] = c;
}

void init()
{
	for(int i = 0; i < N; i++)
		for(int j = 0; j < N; j++)
			g[i][j] = 无边;//初始化为不可达状态【-1】
	// A B C D E F
	// 0 1 2 3 4 5
	// 加边
	add(1, 0, 2);
	add(2, 1, 15);
	add(0, 2, 5);
	add(0, 3, 30);
	add(2, 5, 7);
	add(1, 4, 8);
	add(4, 3, 4);
	add(5, 3, 10);
	add(5, 4, 18);
}

void print()
{
	// 输出邻接矩阵
	cout << "输出邻接矩阵:" << endl;
	cout << "   A  B  C  D  E  F" << endl;
	char c = 'A';
	for (int i = 0; i < N; i++)
	{
		cout << c++ << "  ";
		for (int j = 0; j < N; j++)
			printf("%-2d ",g[i][j]);
//          cout << g[i][j] << " ";
		cout << endl;
	}
}

//深度优先遍历
// u 是当前访问的点
void dfs(int u)
{
	cout << char(u+'A') << " " ;
	vs[u] = true;//标记以访问
	for(int i = 0; i < N; i++)//访问当前结点可达的结点(有边)
	{
		int e = g[u][i];
		if(vs[i])//已访问过
			continue;
		if(e == 无边)//无边
			continue;
		dfs(i);		
	}
}

//广度优先遍历
// u 是当前访问的点
void bfs(int u)
{
	memset(vs,false,sizeof(vs));//初始化访问表为 未访问状态
	vs[u] = true;
	queue<int> q;//队列(先进先出)
	q.push(u);
	while(!q.empty()){
		int t = q.front();//取队头
		cout << char(t+'A') << " " ;
		q.pop();//队头出列
		for(int i = 0; i < N; i++)//访问当前结点可达的结点(有边)
		{
			int e = g[t][i];
			if(vs[i])//已访问过
				continue;
			if(e == 无边)//无边
				continue;
			q.push(i);
			vs[i] = true;
		}
	}
}



int dist[N];//距离数组
int pre[N];//pre[i] 记录最短路径上,点 i 的前一个结点
//输出路径
void printRoute(int x)
{
	cout << "\nA到" << char(x + 'A') << "的最短路径长度为: " << dist[x] << endl;
	cout << "最短路径途径节点:";
	vector<int> v;
	while(x != -1){
		v.push_back(x);
		x = pre[x];
	}
	for(int i = v.size()-1; i >= 0; i--)
		cout << char(v[i]+'A') << " " ;
	cout << endl;
}

//单源最短路 Dijkstra算法
void dijkstra(int u)//u表示起点
{
	cout << "\n\nDijkstra算法求最短路径"<<endl;
	memset(vs,false,sizeof(vs));//初始化访问表为 未访问状态
	memset(dist,0x3f,sizeof(dist));//初始化距离表为 无穷大
	memset(pre,-1,sizeof(pre));//初始化所有结点的前一个节点为 -1
	dist[u] = 0;
	for(int i = 0; i < N; i++)
	{
		int t = -1;
		for(int j = 0; j < N; j++)//找n次
		{
			if(!vs[j] && (t == -1 || dist[j] < dist[t]))//循环找当前最小距离的点
				t = j;
		}
		printRoute(t);
		vs[t] = true;
		for(int j = 0; j < N; j++)//用当前最小距离的点尝试去更新其他点的距离
		{
			if(g[t][j] == 无边)
				continue;
			if(dist[j] > dist[t] + g[t][j])
			{
				dist[j] = dist[t] + g[t][j];
				pre[j] = t;//记录前驱节点
			}
		}	
	}	
}
int main()
{
	init(); // 初始化图
	print(); // 输出邻接矩阵和邻接表
	cout<< "\n深度优先遍历:";
	memset(vs,false,sizeof(vs));//初始化访问表为 未访问状态
	dfs(0);
	cout<< "\n广度优先遍历:";
	bfs(0);
	dijkstra(0);
	return 0;
}

🍻 C

#include<stdio.h>
#include<string.h>
#include<limits.h>
#include<stdbool.h>

#define N 6
#define M (N * N)
#define INF 0x3f3f3f3f
#define NO_EDGE -1

int g[N][N]; // graph数组记录邻接矩阵【-1 表示不可达】
bool vs[N]; // visited数组记录结点是否已经被访问过

void add(int a, int b, int c)
{
    // 邻接矩阵加边
    g[a][b] = c;
}

void init()
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            g[i][j] = NO_EDGE; // 初始化为不可达状态【-1】
        }
    }
    // A B C D E F
    // 0 1 2 3 4 5
    // 加边
    add(1, 0, 2);
    add(2, 1, 15);
    add(0, 2, 5);
    add(0, 3, 30);
    add(2, 5, 7);
    add(1, 4, 8);
    add(4, 3, 4);
    add(5, 3, 10);
    add(5, 4, 18);
}

void print()
{
    // 输出邻接矩阵
    printf("输出邻接矩阵:\n");
    printf("   A  B  C  D  E  F\n");
    char c = 'A';
    for (int i = 0; i < N; i++)
    {
        printf("%c  ", c++);
        for (int j = 0; j < N; j++)
        {
            if (g[i][j] == NO_EDGE)
            {
                printf(" - ");
            }
            else
            {
                printf("%-2d ", g[i][j]);
            }
        }
        printf("\n");
    }
}

//深度优先遍历
// u 是当前访问的点
void dfs(int u)
{
    printf("%c ", u + 'A');
    vs[u] = true; // 标记已访问
    for (int i = 0; i < N; i++) // 访问当前结点可达的结点(有边)
    {
        int e = g[u][i];
        if (vs[i]) // 已访问过
            continue;
        if (e == NO_EDGE) // 无边
            continue;
        dfs(i);
    }
}

//广度优先遍历
// u 是当前访问的点
void bfs(int u)
{
    memset(vs, false, sizeof(vs)); // 初始化访问表为未访问状态
    vs[u] = true;
    printf("%c ", u + 'A');
    int queue[N];
    int front = 0, rear = 0;
    queue[rear++] = u;
    while (front != rear)
    {
        int t = queue[front++];
        for (int i = 0; i < N; i++) //访问当前结点可达的结点(有边)
        {
            int e = g[t][i];
            if (vs[i]) //已访问过
                continue;
            if (e == NO_EDGE) //无边
                continue;
            printf("%c ", i + 'A');
            queue[rear++] = i;
            vs[i] = true;
        }
    }
}

int dist[N];   //距离数组
int pre[N];    //pre[i] 记录最短路径上,点 i 的前一个结点

//输出路径
void printRoute(int x)
{
    printf("\nA到%c的最短路径长度为:%d\n", x + 'A', dist[x]);
    printf("最短路径途径节点:");
    int v[N], cnt = 0;
    while (x != -1)
    {
        v[cnt++] = x;
        x = pre[x];
    }
    for (int i = cnt - 1; i >= 0; i--)
    {
        printf("%c ", v[i] + 'A');
    }
    printf("\n");
}

//单源最短路 Dijkstra算法
void dijkstra(int u) //u表示起点
{
    printf("\n\nDijkstra算法求最短路径\n");
    memset(vs, false, sizeof(vs));   //初始化访问表为未访问状态
    memset(dist, INF, sizeof(dist)); //初始化距离表为无穷大
    memset(pre, -1, sizeof(pre));    //初始化所有结点的前一个节点为-1
    dist[u] = 0;
    for (int i = 0; i < N; i++)
    {
        int t = -1;
        for (int j = 0; j < N; j++) //找n次
        {
            if (!vs[j] && (t == -1 || dist[j] < dist[t])) //循环找当前最小距离的点
                t = j;
        }
        printRoute(t);
        vs[t] = true;
        for (int j = 0; j < N; j++) //用当前最小距离的点尝试去更新其他点的距离
        {
            if (g[t][j] == NO_EDGE)
                continue;
            if (dist[j] > dist[t] + g[t][j])
            {
                dist[j] = dist[t] + g[t][j];
                pre[j] = t; //记录前驱节点
            }
        }
    }
}

int main()
{
    init();  // 初始化图
    print(); // 输出邻接矩阵和邻接表
    printf("\n深度优先遍历:");
    memset(vs, false, sizeof(vs)); //初始化访问表为未访问状态
    dfs(0);
    printf("\n广度优先遍历:");
    bfs(0);
    dijkstra(0);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ快速学习之WorkQueues模型、三种交换机、消息转换器(基于SpringBoot)

文章目录 前言一、WorkQueues模型消息发送消息接收能者多劳 二、交换机类型1.Fanout交换机消息发送消息接收 2.Direct交换机消息接收消息发送 3.Topic交换机消息发送消息接收 三、编程式声明队列和交换机fanout示例direct示例基于注解 四、消息转换器总结 前言 WorkQueues模型…

借助 DPM 代码扫描的力量解锁医疗设备的可追溯性

在当今的医疗保健系统中&#xff0c;医疗设备的可追溯性变得比以往任何时候都更加重要。为了增强现代医疗保健领域的可追溯性和安全性&#xff0c;UDI 条形码充当唯一设备标识的标准&#xff0c;为医疗设备提供唯一标识符。 DataMatrix 代码&#xff08;或直接零件标记代码&am…

矩阵代数与MATLAB实现(特征值、广义特征值、酋矩阵、)

矩阵代数的相关知识 目录 一、特征值与特征向量 1、特征值与特征向量 2、MATLAB计算 二、广义特征值与广义特征向量 1、广义特征值与广义特征向量 2、MATLAB计算 三、酋矩阵 1、酋矩阵 2、MATLAB计算 四、未完待续 总结 提示&#xff1a;以下是本篇文章正文内容&…

动态规划:解决复杂问题的利器(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Android控件全解手册 - 多语言切换完美解决方案(兼容7.0以上版本)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

深入理解OS--硬件高速缓存,缓存一致性,存储设备

存储技术 1.SRAM&#xff0c;DRAM 静态&#xff1a;更快&#xff0c;用作高速缓存存储器。处理器高速缓存采用SRAM。 动态&#xff1a;用作主存及图形系统的帧缓冲区。内存采用DRAM。 2.内存 2.1.内存数据访问示例 设备控制器存在缓存。设备芯片自身存在缓存。 2.2.采用并行…

Spring不再支持Java8了

在今天新建模块的时候发现了没有java8的选项了&#xff0c;结果一查发现在11月24日&#xff0c;Spring不再支持8了&#xff0c;这可怎么办呢&#xff1f;我们可以设置来源为阿里云https://start.aliyun.com/ 。 java8没了 设置URL为阿里云的地址

【Web】NewStarCTF Week3 个人复现

①Include &#x1f350; ?filephpinfo 提示查下register_argc_argv 发现为on LFI包含 pearcmd命令执行学习 pearcmd.php文件包含妙用 ?file/usr/local/lib/php/pearcmd&config-create/<?eval($_POST[a])?>./ha.php ?file./ha post传&#xff1a; asystem…

赛博朋克-MISC-bugku-解题步骤

——CTF解题专栏—— 题目信息&#xff1a; 题目&#xff1a;赛博朋克 作者&#xff1a;Mooooooof 提示&#xff1a; 解题附件&#xff1a; 解题思路&#xff1a; 赛博朋克是个txt文件&#xff1f;&#xff1f;&#xff1f;&#xff0c;不是个game.exe吗&#xff08;开玩笑…

3D场景建模工具

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 1. 什么是3D场景建模&#xff1f; 3D场景建模是一种通过计算机图形学技术&#xff0c;将现实世…

如何跑通跨窗口渲染:multipleWindow3dScene

New 这是一个跨窗口渲染的示例&#xff0c;用 Three.js 和 localStorage 在同一源&#xff08;同产品窗口&#xff09;上跨窗口设置 3D 场景。而这也是本周推特和前端圈的一个热点&#xff0c;有不少人在争相模仿它的实现&#xff0c;如果你对跨窗口的渲染有兴趣&#xff0c;可…

pdf文件编辑,[增删改查]

pdf文件是投标文件中必不可少的格式&#xff0c;传统的方式先编辑word格式&#xff0c;最后生成pdf&#xff0c;但是有时候需要直接编辑pdf文件&#xff0c;编辑pdf的工具无疑 “adobe acrobat dc”是最好用的之一了 1.把图片文件添加到pdf指定位置&#xff0c;例如把一张图片添…

zookeeper集群(很少用)+kafka集群(常用)

一、zookeeper zookeeperkafka&#xff08;2.7.0版本&#xff09; kafka&#xff08;3.4.1版本&#xff09;不依赖于zookeeper 1、定义&#xff1a;zookeeper开源&#xff0c;分布式架构&#xff0c;提供协调服务&#xff08;Apache项目&#xff09;&#xff0c;基于观察者模…

【C语言】把歌词里的播放时间跟歌词提取出来

一&#xff0c;介绍 给到一个字符串&#xff0c;里面包含了时间&#xff08;唱该歌词的时间以及该歌词&#xff09;例如“[02:16.33][04:11.44][05:11.44]我想大声宣布对你依依不舍”&#xff0c;如何把两者都给打印出来呢&#xff1f;下面给出解释 二&#xff0c;代码 #incl…

<蓝桥杯软件赛>零基础备赛20周--第8周第1讲--十大排序

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

fastadmin 如何引入自己的js

在需要的界面中&#xff1a;如何实例说明&#xff1a; 中<script> function zhuruJs(url) { let temp document.createElement( script ); temp.setAttribute( type, text/javascript" );temp.src urL; document.head . appendChild(temp); zhuruJs(location…

轻松愉悦的验证方式:实现图片旋转验证功能

说在前面 在当今互联网时代&#xff0c;随着技术的不断进步&#xff0c;传统的验证码验证方式已经无法满足对安全性和用户体验的需求。为了应对日益狡猾的机器人和恶意攻击&#xff0c;许多网站和应用程序开始引入图形验证码&#xff0c;其中一种备受欢迎的形式就是图片旋转验证…

springmvc实验(三)——请求映射

【知识要点】 方法映射概念 所谓的方法映射就是将前端发送的请求地址和后端提供的服务方法进行关联。在springMVC框架中主要使用Controller和RequestMapping两个注解符&#xff0c;实现请求和方法精准匹配。注解符Controller Spring中包含了一个Controller接口&#xff0c;但是…

【C/C++笔试练习】this指针的概念、初始化列表、const对象调用、构造和析构函数、继承和组合、重载和多态、虚函数的定义、计算日期到天数转换、幸运的袋子

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;this指针的概念&#xff08;2&#xff09;初始化列表&#xff08;3&#xff09;const对象调用&#xff08;4&#xff09;构造和析构函数&#xff08;5&#xff09;继承和组合&#xff08;6&#xff09;重载和多态&#x…

七天.NET 8操作SQLite入门到实战 - 第四天EasySQLite前后端项目框架搭建

前言 今天的主要任务是快速下载并安装.NET 8 SDK&#xff0c;搭建EasySQLite的前后端框架。 .NET 8 介绍 .NET 8 是 .NET 7 的后继版本。 它将作为长期支持 (LTS) 版本得到三年的支持。 使用技术栈和开发环境 咱们的.NET 8操作SQLite入门到实战教程主要使用技术栈为如下所示…