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

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

一、【实验目的】

1、 理解图的存储结构与基本操作;

2、熟悉图的深度度优先遍历和广度优先遍历算法

3、掌握图的单源最短路径算法

二、【实验内容】

1.根据下图(图见实验11)邻接矩阵,编程实现该图的深度与广度优先遍历算法,输出遍历序列。

2.单源节点最短路径问题

问题描述:求从有向图的某一结点出发到其余各结点的最短路径。

基本要求:

(1)有向图采用邻接矩阵表示。

(2)单源节点最短路径问题采用Dijkstra算法。

(3)输出有向图中从源结点T到其余各结点的最短路径和最短路径值。

三、实验源代码

//SequenceList.htypedef struct
{ElemType list[MaxSize];int size;        
} SequenceList;//顺序表初始化 
void ListInitialize(SequenceList *L)
{L->size = 0;
}int ListLength(SequenceList L)
{return L.size;
}//顺序表插入操作 
int ListInsert(SequenceList *L, int i, ElemType x)
{int j;if (L->size >= MaxSize){printf("顺序表已满无法插入!\n");return 0;}else if (i < 0 || i > L->size){printf("参数i不合法!\n");return 0;}else{for (j = L->size; j > i; j--){L->list[j] = L->list[j-1];}L->list[i] = x;L->size++;}return 1;
}int ListDelete(SequenceList *L, int i, ElemType *x)
{int j;if (L->size <= 0){printf("顺序表已空无数据可删!\n");return 0;}else if (i < 0 || i > L->size-1){printf("参数i不合法");return 0;}else{*x = L->list[i];for (j = i+1; j < L->size-1; j++) {L->list[j-1] = L->list[j];}L->size--;return 1;}
}int ListGet(SequenceList L, int i, ElemType *x)
{if (i < 0 || i > L.size-1){printf("参数i不合法!\n");return 0;}else{*x = L.list[i];return 1;}
}SequenceQueue.h
//定义循环队列结构体
typedef struct
{ElemType queue[MaxQueueSize];int rear;int front;int count;} SequenceQueue;//初始化顺序循环队列 
void QueueInitiate(SequenceQueue *Q)
{Q->rear =0;Q->front=0;Q->count=0; 
}//判空 
int QueueNotEmpty(SequenceQueue Q)
{if(Q.count ==0){return 0;}else{return 1;}
}//入队 
int QueueAppend(SequenceQueue *Q,ElemType x)
{if(Q->count>0&&Q->front==(Q->front+Q->count)%40){printf("队列已满无法插入!\n");return 0;}else{Q->queue[Q->rear] = x;Q->rear=(Q->rear+1)%MaxQueueSize;Q->count ++;return 1;}
}//出队 
int QueueDelete(SequenceQueue *Q,int *d)
{if(Q->count==0){printf("循环队列已空无数据元素出队列!\n");return 0;}else{*d=Q->queue[Q->front];Q->front=(Q->front+1)%MaxQueueSize;Q->count--;return 1;}
}
//12.c
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
#define MaxVertices 10
#define MaxEdges 100
#define MaxWeight 10000#define MaxQueueSize 10typedef char ElemType;#include"SequenceList.h" typedef struct
{SequenceList Vertices;int edge[MaxVertices][MaxVertices];int numOfEdges;
}MatrixGraph;typedef struct 
{int row;int col;int weight;
}RCW;//初始化 
void Initiate(MatrixGraph *G,int n)
{int i,j;for(i=0;i<n;i++){for(j=0;j<n;j++){if(i==j){G->edge[i][j]=0;}else{G->edge[i][j]=MaxWeight;}}}G->numOfEdges=0;//边的条数置为0 ListInitialize(&G->Vertices);//顺序表初始化 
}//插入顶点
void InsertVertex(MatrixGraph *G,ElemType vertex)
{ListInsert(&G->Vertices,G->Vertices.size,vertex);// } //插入边 void InsertEdge(MatrixGraph *G,int v1,int v2,int weight){if(v1<0||v1>G->Vertices.size||v2<0||v2>G->Vertices.size){printf("参数v1或参数v2越界出错!\n");return; } G->edge[v1][v2]=weight;G->numOfEdges++;}void CreatGraph(MatrixGraph *G,ElemType V[],int n,RCW E[],int e)
{int i,k;Initiate(G,n);for(i=0;i<n;i++){InsertVertex(G,V[i]);}for(k=0;k<e;k++){InsertEdge(G,E[k].row,E[k].col,E[k].weight);} 
}//取第一个邻接顶点
int GetFirstVex(MatrixGraph G,int v,int visited[])
{int col;if(v<0||v>G.Vertices.size){printf("参数v1越界出错!\n");return -1;}for(col=0;col<=G.Vertices.size;col++){if(!visited[col])if(G.edge[v][col]>0&&G.edge[v][col]<MaxWeight){return col;}}return -1;} //取下一个邻接顶点int GetNextVex(MatrixGraph G,int v1,int v2,int visited[]){int col;if(v1<0||v1>G.Vertices.size||v2<0||v2>G.Vertices.size){printf("参数v1或v2越界出错!\n");return -1;}for(col=v2+1;col<=G.Vertices.size;col++){if(!visited[col]){if(G.edge[v1][col]>0&&G.edge[v1][col]<MaxWeight){return col;}}}return -1;} //深度优先遍历
void DepthFSearch(MatrixGraph G,int v,int visited[])
{int w;printf("%c ",G.Vertices.list[v]);visited[v]=1;w=GetFirstVex(G,v,visited);while(w!=-1) {if(!visited[w])DepthFSearch(G,w,visited);w=GetNextVex(G,v,w,visited);}} //引用顺序队列头文件 #include"SequenceQueue.h"//取第一个邻接顶点
int GetFirstVex2(MatrixGraph G,int v,int visited[])
{int col;if(v<0||v>G.Vertices.size){printf("参数v1越界出错!\n");return -1;}for(col=0;col<=G.Vertices.size;col++){if(G.edge[v][col]>0&&G.edge[v][col]<MaxWeight){return col;}}return -1;} //广度优先遍历void BroadFSearch(MatrixGraph G,int v,int visited2[]){int u,w;SequenceQueue queue;printf("%c ",G.Vertices.list[v]);visited2[v]=1;QueueInitiate(&queue);QueueAppend(&queue,v);while(QueueNotEmpty(queue)){QueueDelete(&queue,&u);//传地址? w=GetFirstVex2(G,u,visited2);while(w!=-1){if(!visited2[w]){printf("%c ",G.Vertices.list[w]);visited2[w]=1;QueueAppend(&queue,w);}w=GetNextVex(G,u,w,visited2);}}} //狄克斯特拉算法找最短路径
//带权图G从下标v0顶点到其他顶点的最短距离distance
//和最短路径下标path 
void Dijkstra(MatrixGraph G,int v0,int distance[],int path[]) 
{ int n=G.Vertices.size;int *s=(int*)malloc(sizeof(int)*n);int minDis,i,j,u;for(i=0;i<n;i++)//初始化{distance[i]=G.edge[v0][i];s[i]=0;if(i!=v0&&distance[i]<MaxWeight)path[i]=v0;elsepath[i]=-1;} s[v0]=1;for(i=1;i<n;i++){minDis=MaxWeight;for(j=0;j<=n;j++)//在还未找到最短路径的顶点集中选有最短距离的顶点u {if(s[j]==0&&distance[j]<minDis){u=j;minDis=distance[j];}}if(minDis==MaxWeight)//当已不存在路径时算法结束 return;s[u]=1;//标记顶点u已从集合T加入到集合S中 for(j=0;j<n;j++)//修改从v0到其他顶点的最短距离和最短路径 {if(s[j]==0&&G.edge[u][j]<MaxWeight&&distance[u]+G.edge[u][j]<distance[j]){distance[j]=distance[u]+G.edge[u][j];path[j]=u;} } }
}//正序输出最短路径
printfpath(MatrixGraph g1,int path[])
{char path2[6];int i,j,k;for(i=1;i<6;i++){printf("\n");j=i;k=0;while(j!=-1){path2[k]=g1.Vertices.list[j];k++;j=path[j];	}k--;printf("%c",path2[k]);while(k>0){k--;printf("->%c",path2[k]);}} } void main(void)
{MatrixGraph g1;ElemType a[]={'A','B','C','D','E','F'};RCW rcw[]={{0,2,5},{0,3,30},{1,0,2},{1,4,8},{2,1,15},{2,5,7},{4,3,4},{5,3,10},{5,4,18}};int n=6,e=9;int i,j;CreatGraph(&g1,a,n,rcw,e);printf("顶点集合为:");for(i=0;i<g1.Vertices.size;i++){printf("%c  ",g1.Vertices.list[i]);} printf("\n");printf("邻接矩阵为:\n");for(i=0;i<g1.Vertices.size;i++){for(j=0;j<g1.Vertices.size;j++){printf("%5d  ",g1.edge[i][j]);}printf("\n");}printf("深度优先遍历结果为:"); int visited[6]={};DepthFSearch(g1,0,visited);printf("\n");int visited2[6]={};printf("广度优先遍历结果为:");BroadFSearch(g1,0,visited2); printf("\n");printf("源结点T到其余各结点的最短路径为:");int distance[6];int path[6]={-1};Dijkstra(g1,0,distance,path);printfpath(g1,path);printf("\n");printf("源结点T到其余各结点的最短路径值为:");for(i=0;i<n;i++){printf("\n%c->%c:",g1.Vertices.list[0],g1.Vertices.list[i]);printf("%d",distance[i]);}
}

四、实验结果
在这里插入图片描述

五、实验总结
总结狄克斯特拉算法:
首先,使用 malloc 分配了一个大小为 n 的整型数组 s,用于标记顶点是否已经加入集合 S 中。
然后进行了初始化,初始化了距离数组 distance 和标记数组 s,以及路径数组 path。初始化时,将源顶点 v0 到其他顶点的距离和路径进行了设置。
接下来使用一个循环来依次将未加入集合 S 中的顶点加入,并更新最短路径和最短距离。在每次循环中,首先找到未加入集合 S 中且距离最短的顶点 u,然后将其标记为已加入集合 S 中。
在找到顶点 u 后,再次遍历所有未加入集合 S 中的顶点,更新从源顶点 v0 到其他顶点的最短距离和最短路径。如果通过顶点 u 可以找到更短的路径,就更新距离数组 distance 和路径数组 path。
最终得到的 distance 数组中存储了从源顶点 v0 到各顶点的最短距离,path 数组中存储了相应的最短路径。

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

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

相关文章

刚刚,ChatGPT推出Windows客户端!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

C# + SQLiteExpert 进行(cipher)加密数据库开发+Costura.Fody 清爽发布

一&#xff1a;让 SQLiteExpert 支持&#xff08;cipher&#xff09;加密数据库 SQLiteExpert 作为SQlite 的管理工具&#xff0c;默认不支持加密数据库的&#xff0c;使其成为支持&#xff08;cipher&#xff09;加密数据库的管理工具&#xff0c;需要添加e_sqlcipher.dll &…

1997-2022年各省农作物总播种面积数据(无缺失)

1997-2022年各省农作物总播种面积数据 1、时间&#xff1a;1997-2022年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;农作物总播种面积(千公顷) 4、范围&#xff1a;31省 5、缺失情况&#xff1a;无缺失 6、指标解释&#xff1a;农作物播种面积指农业生…

PCL 点云配准-改进的RANSAC算法(粗配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 计算FPFH特征 2.1.2 RANSAC配准 2.1.3 可视化点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff0…

基于SSM高校课程评价的设计

教师账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;指标信息管理&#xff0c;课程信息管理&#xff0c;教师自评管理 学生账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;课程信息管理&#xff0c;学生评价管理 开发系统&#xff1a;…

不坑盒子在哪儿下载?

不坑盒子是一款Office办公软件的插件&#xff0c;支持MicroSoft Office和WPS的三件套&#xff08;Word、Excel、PPT&#xff09;。 可以为你的Office软件增加数百个实用功能&#xff0c;比如&#xff1a;自动排版、智能写作、仿手写、全文加拼音、稿子模板、一键删除、数据分发…

SAP物料凭证报表字段调整

业务场景&#xff1a; 报表MB51的输入和输出字段调整&#xff1a; 输入&#xff08;选择界面&#xff09; 输出界面 可以看到在这是没有布局调整的 后台路径&#xff1a; SPRO-物料管理-库存管理和实际库存-报表-定义物料凭证列表的字段选择 事务码&#xff1a;SM30-V_MMI…

docker构建jar镜像

文章目录 构建 DockerFile将jar包上传到创建的目录当中在目录中创建 Dockerfile 文件构建镜像创建并启动容器说明 构建 DockerFile [root192 /]# mkdir my [root192 /]# cd my [root192 my]# 将jar包上传到创建的目录当中 在目录中创建 Dockerfile 文件 vi Dockerfile FROM …

MFC工控项目实例二十四模拟量校正值输入

承接专栏《MFC工控项目实例二十三模拟量输入设置界面》 对模拟量输入的零点校正值及满量程对应的电压值进行输入。 1、在SenSet.h文件中添加代码 #include "BtnST.h" #include "ShadeButtonST.h"/ // SenSet dialogclass SenSet : public CDialog { // Co…

RPC通讯基础原理

1.RPC&#xff08;Remote Procedure Call&#xff09;概述 RPC是一种通过网络从远程计算机上调用程序的技术&#xff0c;使得构建分布式计算更加容易&#xff0c;在提供强大的远程调用能力时不损失本地调用的语义简洁性&#xff0c;提供一种透明调用机制&#xff0c;让使用者不…

Leetcode 跳跃游戏 二

核心任务是找出从数组的起点跳到终点所需的最小跳跃次数。 这段代码解决的是“跳跃游戏 II”&#xff08;Leetcode第45题&#xff09;&#xff0c;其核心任务是找出从数组的起点跳到终点所需的最小跳跃次数。 class Solution {public int jump(int[] nums) {//首先处理特殊情…

【文化课学习笔记】【化学】选必三:同分异构体的书写

【化学】选必三&#xff1a;同分异构体的书写 如果你是从 B 站一化儿笔记区来的&#xff0c;请先阅读我在第一篇有机化学笔记中的「读前须知」(点开头的黑色小三角展开)&#xff1a;链接 链状烃的取代和插空法 取代法 一取代物 甲烷、乙烷、丙烷、丁烷的种类 甲烷&#xff1a;只…

【AAOS】Android Automotive 14模拟器源码下载及编译

源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r20 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch sdk_car_x86_64-trunk_staging-eng make -j8 运行效果 emualtor Home All apps …

计算机是如何输入存储输出汉字、图片、音频、视频的

计算机是如何输入存储输出汉字、图片、音频、视频的 为了便于理解&#xff0c;先了解一下计算机的组成。 冯诺依曼计算机的五大组成部分。分别是运算器、控制器、存储器、输入设备和输出设备。参见下图&#xff1a; 一、运算器 运算器又称“算术逻辑单元”&#xff0c;是计算…

Android Camera2在textureView中的预览和拍照

Camera2预览和拍照 1、Camera2相机模型2、Camera2的重要类3、Camera2调用流程4、Camera2调用实现 1)定义TextureView作为预览界面2)设置相机参数3)开启相机4)开启相机预览5)实现PreviewCallback6)拍照 1、Camera2相机模型 解释上诉示意图&#xff0c;假如想要同时拍摄两张不同…

图像及视频的基本操作

文章目录 一、认识计算机中的图像二、图像数据的读取三、数据读取-视频四、图像的其他操作 一、认识计算机中的图像 一张彩色图片是由很多个像素点组合而成的&#xff0c;而一个像素点是由R G B三个通道组成。RGB代表红色&#xff08;Red&#xff09;、绿色&#xff08;Green&a…

【远程监控新体验】OpenObserve结合内网穿透无公网IP远程访问全攻略

文章目录 前言1. 安装Docker2. Docker镜像源添加方法3. 创建并启动OpenObserve容器4. 本地访问测试5. 公网访问本地部署的OpenObserve5.1 内网穿透工具安装5.2 创建公网地址6. 配置固定公网地址前言 本文主要介绍如何在Linux系统使用Docker快速本地化部署OpenObserve云原生可观…

MacOS RocketMQ安装

MacOS RocketMQ安装 文章目录 MacOS RocketMQ安装一、下载二、安装修改JVM参数启动关闭测试关闭测试测试收发消息运行自带的生产者测试类运行自带的消费者测试类参考博客&#xff1a;https://blog.csdn.net/zhiyikeji/article/details/140911649 一、下载 打开官网&#xff0c;…

并发-线程

1, 线程 线程(thread)也是并发的一种形式&#xff0c;线程是比进程更小的活动单位&#xff0c;一个进程中可以有多个线程&#xff0c;线程是进程内部的一个执行分支。 一个进程刚开始时只有一个线程(称之为主线程)&#xff0c;后续的代码中可以创建新的线程&#xff0c;可以指…

git提交到github个人记录

windows下git下载 1.进入git官网https://git-scm.com/downloads/win 一直默认选项即可 2.在settings中SSH and GPG keys中Add SSH key 3.选择git cmd git使用 1.配置用户名&#xff0c;和邮箱 git config --global user.email "youexample.com" git config --g…