图的创建和BFS,DFS遍历

news2024/11/19 23:15:13

图的创建        

        图是一种用于表示对象及其关系的抽象数据结构,由节点(也称为顶点)和连接节点的边组成。图可以分为有向图(Directed Graph)和无向图(Undirected Graph),以及加权图(Weighted Graph)和非加权图(Unweighted Graph)。

本文以无向图为例,用邻接矩阵法来进行图的构建。

邻接矩阵(Adjacency Matrix):

        1.一个二维数组,用于表示节点之间的连接关系。这里 1 表示相连,0 表示不相连。
        2.如果节点 i 和节点 j 之间有边,则 matrix[i][j] 为 1(有向图)或 matrix[i][j] 和 matrix[j][i] 为 1(无向图)。

下面是一个图的例子:

首先我们来定义图结构体:

typedef struct Graph {
	char* vexs; //顶边的标签
	int** arcs; //顶点
	int vexsNum; //标签个数,也可以理解为顶点数
	int arcsNum; //边的个数
}Graph;

        这里vexs是字符串类型是char*,arcs是二级指针模拟二维数组,vexsNum是顶点个数,arcsNum是边的个数。

接着是创建图,为图开辟空间:

Graph* Graph_Init(int num) {
	Graph* G = (Graph*)malloc(sizeof(Graph));
	G->vexs = (char*)malloc(sizeof(char) * num);
	G->arcs = (int**)malloc(sizeof(int*) * num);
	for (int i = 0; i < num; i++) {
		(G->arcs)[i] = (int*)malloc(sizeof(int) * num);
	}
	G->vexsNum = num;
	G->arcsNum = 0;
	return G;
}

        为二级指针开辟vexsNum个一级指针,再为一级指针开辟vexsNum个int空间,这就是二级指针模拟二维数组。如果arcs[i][j]不为0,那么就边数+1,因为加了2遍,所以最后除以2。

void Graph_creat(Graph* G,char* vexs,int* data_vexs) {
	for (int i = 0; i < G->vexsNum; i++) {
		G->vexs[i] = vexs[i];
		for (int j = 0; j < G->vexsNum; j++) {
			G->arcs[i][j] = *(data_vexs + i * G->vexsNum + j);
			if (G->arcs[i][j] == 0) {
				G->arcsNum++;
			}
		}
	}
	G->arcsNum=G->arcsNum/2;
}

接下来就是BFS和DFS遍历:

广度优先搜索 (BFS)

        BFS 算法是从图的一个起始节点开始,探索所有邻居节点,然后逐层向外扩展。通常使用队列数据结构来实现。(类似于树的层级遍历,相当于广撒网)

我们可以写出一个类似于这样的代码:

void BFS(Graph* G,Queue* Q,int*visited,int index) {
    入队第一个顶点
	while (队列不为空)
	{
        出队取得顶点,并且打印顶点。
		for (int i = 0; i < G->vexsNum; i++) {
            //for循环寻找该顶点的相连顶点
			if (如果该顶点与另外一个顶点有联系 && 另外一个顶点没被访问过) {
                入队另外一个顶点
			}
		}
	}
}

        现在的主要问题是如何确定这个元素是否被访问过,我们需要标记访问过的元素。
        我们可以用一个数组来标记,例如如果访问过第二个元素,那么数组对应的位置array[1]就标记为1,其余仍然为0。在每次入队之后置为1,这样会避免多次入队多次访问。 

创建队列的函数就不再写了,最终代码如下:

void BFS(Graph* G,Queue* Q,int*visited,int index) {
	enQueue(Q, index);
	visited[index] = 1;
	while (!Isempty(Q))
	{
		index = deQueue(Q);
		printf("%c ", G->vexs[index]);
		for (int i = 0; i < G->vexsNum; i++) {
			if (G->arcs[index][i] == 1 && visited[i] != 1) {
				enQueue(Q, i);
				visited[i] = 1;
			}
		}
	}
}

深度优先搜索 (DFS)

        DFS 算法是从图的一个起始节点开始,沿着一个路径尽可能深入,然后回溯并探索其他路径。通常使用栈数据结构(递归调用栈或显式栈)来实现。这里用递归实现(相当于一条路走到黑,没路了再回去走其他路)。

我们可以先写出类似这样的代码:

void DFS(Graph* G, int* visited, int index) {
    接收访问顶点并且标记已访问
	for (int i = 0; i < G->vexsNum; i++) {
        //for循环寻找顶点的相连顶点
		if (如果和其他顶点有联系 && 其他顶点未访问) {
			DFS(G, visited, i);//递归其他顶点
		}
	}
}

最后我们可以写出下面的代码:

void DFS(Graph* G, int* visited, int index) {
	printf("%c", G->vexs[index]);
	visited[index] = 1;
	for (int i = 0; i < G->vexsNum; i++) {
		if (G->arcs[index][i] == 1 && visited[i] == 0) {
			DFS(G, visited, i);
		}
	}
}

这就是文章的全部内容了,希望对你有所帮助,如有错误欢迎指出。

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

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

相关文章

Chrome 源码阅读:跟踪一个鼠标事件的流程

我们通过在关键节点打断点的方式&#xff0c;去分析一个鼠标事件的流程。 我们知道chromium是多进程模型&#xff0c;那么&#xff0c;我们可以推测&#xff1a;一个鼠标消息先从主进程产生&#xff0c;再通过跨进程通信发送给渲染进程&#xff0c;渲染进程再发送给WebFrame&a…

elementUI - 折叠以及多选的组件

//子组件 <template><!-- 左侧第二个 --><div class"left-second-more"><div class"layer-list-wrapper1"><el-collapse v-model"activeNames" change"handleChange"><el-collapse-item v-for"…

企业必备技能-打造全屏轮播图的终极指南

标题&#xff1a;“视觉盛宴&#xff1a;打造全屏轮播图的终极指南” 引言 在网页设计中&#xff0c;轮播图是一种常见的视觉元素&#xff0c;它能够吸引访客的注意力并展示重要内容。本文档将指导你如何使用HTML和CSS快速创建一个全屏轮播图&#xff0c;使您的网站更加生动和…

react-学习基础偏

1.新建文件夹 2.vscode引入这个文件夹 3.打开vscode终端 执行命令 npx create-react-app react-basic 创建基本项目&#xff08;react-basic项目文件夹名&#xff09; 4.进入到这个文件夹 可用的一些命令 这就算启动成功 5. 这是项目的核心包 渲染流程

免费实现网站HTTPS访问

HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是一种基于SSL协议的HTTP安全协议&#xff0c;旨在为客户端&#xff08;浏览器&#xff09;与服务器之间的通信提供加密通道&#xff0c;确保数据在传输过程中的保密性、完整性和身份验证。与传统的HTTP相比&a…

​​​​​​ 基于Nmap的异步无状态端口扫描技术

​​​​​​ 基于Nmap的异步无状态端口扫描技术 传统的端口扫描&#xff0c;主要是依靠TCP三次握手去连接&#xff0c;而建立连接的各个过程都存在连接状态&#xff0c;这些状态由操作系统在底层实现存储&#xff0c;可利用这些状态对应用层的数据进行处理。但是&#xff0c;…

2024-06-07 Unity 编辑器开发之编辑器拓展8 —— Scene 窗口拓展

文章目录 1 Handles 类1.1 Scene 响应函数1.2 自定义窗口中监听 Scene1.3 Handles 常用 API2.2.1 颜色控制2.2.2 文本2.2.3 线段2.2.4 虚线2.2.5 圆弧2.2.6 圆2.2.7 立方体2.2.8 几何体2.2.9 移动、旋转、缩放2.2.10 自由移动 / 旋转 2 Scene 窗口中显示 GUI3 HandleUtility4 G…

AI产品经理岗位需求量大吗?好找工作吗?

前言 在当今这个科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;已不再仅仅是一个遥远的概念&#xff0c;而是深深嵌入到我们生活的方方面面&#xff0c;从日常的语音助手到复杂的自动驾驶系统&#xff0c;AI的触角无处不在。随着AI技术的广泛应用和持续进…

react native中内容占位效果

react native中内容占位效果 效果实例图实例代码skeleton.jsx 效果实例图 实例代码skeleton.jsx import React, { useEffect, useRef } from "react"; import { Animated, StyleSheet, View } from "react-native"; import { pxToPd } from "../../.…

“开源与闭源:AI大模型发展的未来之路“

文章目录 每日一句正能量前言数据隐私开源大模型与数据隐私闭源大模型与数据隐私数据隐私保护的共同考虑结论 商业应用开源大模型的商业应用优势&#xff1a;开源大模型的商业应用劣势&#xff1a;闭源大模型的商业应用优势&#xff1a;闭源大模型的商业应用劣势&#xff1a;商…

vue3+ts 拖拽容器边缘,改变容器宽度和高度

例如&#xff1a;我们的代码编辑器 终端与代码区&#xff0c;可以纵向拖拽&#xff0c;改变两个容器高度 目录与代码区可以横向拖拽&#xff0c;改变两个容器宽度 本文使用vue3tstailwindcss&#xff0c;把横向纵向整合在一起写了&#xff0c;也可以分开使用 utils目录下新建…

【AIoT-Robot】3d hand pose

手语是聋哑人士的主要沟通工具,它是利用手部和身体的动作来传达意义。虽然手语帮助它的使用者之间互相沟通,但聋哑人士与一般人的沟通却十分困难,这个沟通障碍是源于大部分人不懂得手语。 1. 手势&&手语 手势:手的姿势 ,通常称作手势。它指的是人在运用手臂时,所…

基因分析平台开发1 - Layui WebUI组件库快速地构建网页界面

介绍一个Web UI库&#xff0c;可快速实现基因分析平台前端部分的开发&#xff0c;借助帮助文档&#xff0c;快速实现自己想要效果。 1. Layui 简介 Layui 是一套免费的开源 Web UI 组件库&#xff0c;可用于更简单快速地构建网页界面&#xff0c;全部主流 Web 浏览器&#xf…

【Java】解决Java报错:ClassCastException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 错误的类型转换2.2 泛型集合中的类型转换2.3 自定义类和接口转换 3. 解决方案3.1 使用 instanceof 检查类型3.2 使用泛型3.3 避免不必要的类型转换 4. 预防措施4.1 使用泛型和注解4.2 编写防御性代码4.3 使用注解和检查工具 5. 示…

这才是计科之 Onix XV6 源码分析(1、XV6-x86的启动)

这才是计科之 Onix & XV6 源码分析&#xff08;1、XV6-x86的启动&#xff09; 前言 Onix是一款相对于XV6来说功能更为健全的单核OS&#xff0c;由于功能更加完善&#xff0c;Onix也更加复杂。代码阅读起来会比较绕。 XV6是一款简单易读的多核操作系统&#xff0c;但其功…

openh264 降噪功能源码分析

文件位置 ● openh264/codec/processing/denoise/denoise.cpp ● openh264/codec/processing/denoise/denoise_filter.cpp 代码流程 说明&#xff1a;从代码流程可以看到&#xff0c;实现降噪的核心功能主要就是BilateralDenoiseLuma、WaverageDenoiseChroma两个函数。 原理…

[word] word大括号怎么打两行 #其他#其他#微信

word大括号怎么打两行 Word给用户提供了用于创建专业而优雅的文档工具&#xff0c;帮助用户节省时间&#xff0c;并得到优雅美观的结果。 一直以来&#xff0c;Microsoft Office Word 都是最流行的文字处理程序。 作为 Office 套件的核心程序&#xff0c; Word 提供了许多易…

ChatGPT-4o提示词的九大酷炫用法,你知道几个?

ChatGPT-4o提示词的九大酷炫用法&#xff0c;你知道几个&#xff1f;&#x1f680; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典…

android antirollback verno 获取方法

ReadRollbackIndex.exe 获取 调查avbVBMeta结构体 typedef struct AvbVBMetaImageHeader { /* 0: Four bytes equal to "AVB0" (AVB_MAGIC). */ uint8_t magic[AVB_MAGIC_LEN]; /* 4: The major version of libavb required for this header. */ uint32_t…