无向图-邻接链表的深度优先遍历-DFS

2023-10-27

一、DFS思想

本算法以无向网为例,存储方式采用邻接链表

1)将该网以邻接链表的方式存储
2)选取A点为起始点,访问此顶点,用一个visit的bool型数组记录访问状态(false表示未被访问,true表示已访问)
3)从A的未被访问的邻接点出发,深度优先遍历图,直到图中所有和v有路径相通的顶点都被访问到


二、算法复杂度:O(n+e)

        邻接矩阵和邻接表都是实现BFS和DFS的方法,邻接矩阵时间复杂度为O(n^2),邻接表的时间复杂度为O(n+e)。因此邻接矩阵适用于稠密图,邻接表适用于稀疏图。


三、在实际编写代码时,笔者发现

1)对采用邻接链表作为存储方式的图做DFS时,由于建立邻接链表时可采用不同的插入方法:比如头插法和尾插法,会使得做DFS时相同的图结构会有不一样的结果;

2)即使相同的图结构,采用不同的存储方式(邻接矩阵和邻接链表)做DFS时,它们的结果有时也会不一样;

笔者认为这都是正常现象,DFS的思想还是没变。


四、测试用例图

本算法的测试用例为《大话数据结构》p239中的图7-5-2。如下图所示:


五、C代码实现

/*******************************************************************************************
【DFS】
Author:tmw
date:2018-2-20
********************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


#define MAX_VERTEX 100
#define inf 65535  //表示两点之间没有边相连

int visit[MAX_VERTEX];   //标记顶点是否被访问

/**无向图的邻接链表的建立**/
//边表结点数据结构
typedef struct EdgeNode
{
    int adjvex;  //存储该顶点对应的下标
    int weight;
    struct EdgeNode *next; //指向下一个邻接点
}EdgeNode;

//顶点表结点数据结构
typedef struct VertexNode
{
    char Vertex;  //存储顶点信息
    EdgeNode *FistEdge; //边表头指针
}VertexNode,AdjList[MAX_VERTEX];

//邻接链表图的数据结构
typedef struct
{
    AdjList adjList;
    int VertexNumber,EdgeNumber; //顶点数和边数
}GraphAdjList;


/**无向图邻接链表的建立**/
void Create_no_direction_LinkList_Graph(GraphAdjList *G)
{
    int i,j,w,k;
    printf("请输入无向图邻接链表的顶点数和边数:\n");
    scanf("%d %d",&G->VertexNumber,&G->EdgeNumber);

    //输入顶点信息,建立顶点表
    printf("顶点表的建立:输入顶点信息,如ABCDEF.....\n");
    char ch;
    while( ( ch = getchar()  != '\n' ) );
    for(i=0;i<G->VertexNumber;i++)
    {
        scanf("%c",&G->adjList[i].Vertex);
        G->adjList[i].FistEdge = NULL;
    }
    printf("边表的建立:输入边(vi,vj)的顶点下标,权值统一为1,如:0 1 1(权值)\n");

    for(k=0;k<G->EdgeNumber;k++)
    {
        scanf("%d %d %d",&i,&j,&w);

        EdgeNode *e;
        e = (EdgeNode*)malloc(sizeof(EdgeNode));
        e->weight = w;
        e->adjvex = j;
        e->next = G->adjList[i].FistEdge;   //头插法将下标为j的顶点插入与之相连的下标为i的结点链表中
        G->adjList[i].FistEdge = e;

        //无向图,因此是对称的,同样的操作将下标为i的顶点插入与之相连的下标为j的结点的链表中
        e = (EdgeNode*)malloc(sizeof(EdgeNode));
        e->weight = w;
        e->adjvex = i;
        e->next = G->adjList[j].FistEdge;
        G->adjList[j].FistEdge = e;
    }


//    打印检查
    printf("---------------------构造出来的无向图邻接链表的边信息如下---------------------\n");
    for(i=0;i<G->VertexNumber;i++)
    {
        EdgeNode *p;
        p = G->adjList[i].FistEdge;
        printf("%d\t",i);
        while(p != NULL)
        {
            printf("%d ",p->adjvex);
            p = p->next;
        }
        printf("\n");
    }
}

//无向图的邻接链表的第i个顶点的DFS
void DFS(GraphAdjList G, int i)
{
    visit[i] = true;
    printf("%c ",G.adjList[i].Vertex);

    EdgeNode *p;
    p = G.adjList[i].FistEdge;

    while(p)
    {
        if( !visit[p->adjvex] )
            DFS(G,p->adjvex);
        p = p->next;
    }
}

//对整个无向图进行DFS
void DFS_Travel(GraphAdjList G)
{
    int i;

    //先初始化visit数组
    for(i=0;i<G.VertexNumber;i++)
        visit[i] = false;

    printf("无向图的邻接链表DFS结果为:\n");
    for(i=0;i<G.VertexNumber;i++)
        if(!visit[i])
            DFS(G,i);
}

六、测试代码及测试结果

int main()
{
    printf("测试代码\n");
    GraphAdjList G;
    Create_no_direction_LinkList_Graph(&G);
    DFS_Travel(G);
    return 0;
}

测试结果如下:


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无向图-邻接链表的深度优先遍历-DFS 的相关文章

  • QT<五> 对话框

    一 对话框 1 基本概念 对话框通常会是一个顶层窗口 出现在程序最上层 用于实现短期任务或者简洁的用户交互 Qt 中使用QDialog类实现对话框 就像主窗口一样 我们通常会设计一个类继承QDialog QDialog 及其子类 以及所有Q
  • Hadoop实现KNN算法

    本人java基础较弱 有什么需要改进的欢迎大家评论 Hadoop实现KNN算法 一 环境 二 数据说明 三 MapReduce设计 1 KNN算法的基本思想即传统KNN算法的的性能瓶颈 2 并行化KNN设计思想 3 map函数设计 4 re

随机推荐

  • 【C语言学习】C语言函数

    C语言学习 C语言函数 函数的概念 函数的定义方法 函数的分类 从定义角度分类 即函数是谁实现的 从参数角度分类 函数的声明 什么时候需要声明 怎么声明呢 声明的方法 函数的调用 函数的调用方法 使用函数的好处 小总结 变量的存储类别 内存
  • Ubuntu创建Eclipse桌面快捷方式

    Ubuntu1404LTS创建Eclipse桌面快捷方式 cd usr share applications sudo gedit eclipse desktop 填写以下内容 注意每行后面不能有空格 Desktop Entry Encod
  • Python语言学习实战-内置函数all()和any()的使用(附源码和实现效果)

    实现功能 all 和any 函数都是Python的内置函数 用于对布尔值进行操作 all 函数接受一个可迭代对象作为参数 如果可迭代对象中所有元素都为真值 即非零 非空 非None等 则返回True 否则返回False any 函数接受一个
  • 【成电860考研】经验贴汇总(专业课部分)-扒遍所有网站:信软群、王道、知乎、csdn等,截止21年7月整理出的所有帖子-共15篇

    1 单词哥 专业课一共两本书 然而软工那本书也不大需要看 对应试帮助 不大 重点还是看学校老师的 PPT 而计算机网络那本黑书就是非常 重要了 尤其是课后的习题简直是要多刷 毕竟保不准就有原题 计算机网络从 8 月开始 首先自己啃书 确实有
  • Unity小游戏之闯关小游戏

    游戏场景预设图 玩法 使蓝色的小球触碰到黄色的开关让门降下去 并且不触碰任何东西进入下一关 介绍 蓝色的小球是玩家 黄色的是开关用来开绿色点前面的门 红色的是障碍物 黑色的是墙 创建场景以及绑定代码 首先搭建一个场景把地板的Plane命名为
  • 微内核操作系统综述

    一 文章介绍 二 内核与操作系统的关系 三 微内核核心思想 四 各种内核的优缺特点以及上下代之间演变的过程 一 文章介绍 文章主要介绍各种微内核以及它在操作系统中的演变 二 内核与操作系统的关系 内核 是一个操作系统的核心 是基于硬件的第一
  • etcd常用命令与备份恢复-Day03

    1 etcd简介 官方网站 etcd io 官方文档 etcd io docs v3 5 op guide maintenance 官方硬件推荐 etcd io docs v3 5 op guide hardware github地址 gi
  • 设置浏览器兼容

    浏览器兼容 css兼容 cursor定义手型 Firefox不支持hand IE支持pointer 解决方法 统一使用pointer css透明 IE filter progid DXImageTransform Microsoft Alp
  • STM32异常与中断

    一 中断的基本概念 中断的定义及中断工作方式 中断 即CPU在正常执行程序的过程中 遇到外部 例如常见的按键中断 内部 例如定时器中断 的紧急事件需要处理 暂时中断 中止 当前程序的执行 而转去为事件服务 待服务完毕 再返回到暂停处 断点
  • iffDetector-目标检测新优化算法

    想法直接 提升有限 论文地址 https arxiv org pdf 2006 12708 pdf Github地址 https github com anonymous2020new iffDetector Abstract 基于现代CN
  • C++数据结构——杨辉三角

    杨辉三角 杨辉 字谦光 汉族 钱塘 今浙江省杭州 人 南宋杰出的数学家 他曾担任过南宋地方行政官员 为政清廉 足迹遍及苏杭一带 他在总结民间乘除捷算法 垛积术 纵横图 幻方 以及数学教育方面 均做出了重大的贡献 他是世界上第一个排出丰富的纵
  • Android:JNI调用 出错java.lang.UnsatisfiedLinkError: No implementation found for解决办法

    在项目中使用第三方so库 调用JNI时发现了这个错误 java lang UnsatisfiedLinkError No implementation found for 仔细查看了代码 没发现有出错的地方 然后上网查资料 发现这个问题答案
  • three.js设置物体的缩放和旋转

    一 缩放物体介绍 1 如何缩放 使用three js设置物体的缩放可以通过对象的scale属性来实现 例如 将一个立方体对象缩小一半的代码如下 var cube new THREE Mesh new THREE BoxGeometry 1
  • Linux 之 利用Google Authenticator实现用户双因素认证

    一 介绍 什么是双因素认证 双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统 双因素认证是一种采用时间同步技术的系统 采用了基于时间 事件和密钥三变量而产生的一次性密码来代替传统的静态密码 每个
  • Python函数中的实参和形参

    文章目录 一 形参和实参的概念 二 四大参数 4 1位置参数 4 2默认参数 4 3 可变参数 4 4 关键字参数 一 形参和实参的概念 函数的参数分为形参 形式参数 和实参 实际参数 形参又分为 位置参数 默认参数 可变参数 关键字参数
  • c语言旧键盘打字,PAT 乙级 1033. 旧键盘打字 C语言

    1033 旧键盘打字 20 题目 旧键盘上坏了几个键 于是在敲一段文字的时候 对应的字符就不会出现 现在给出应该输入的一段文字 以及坏掉的那些键 打出的结果文字会是怎样 输入格式 输入在2行中分别给出坏掉的那些键 以及应该输入的文字 其中对
  • HTML5 canvas标签-5 浮雕算法

    浮雕算法 顾名思义 就是将图像变成类似石头雕塑的算法 来源于百度 这就是一个浮雕 我们看看它的特点 首先颜色整体 偏灰 上一篇博客中说过 在RGB中 R G B时便是灰色 其次就是层次分明 所以根据上述这两点 我们代码首先需要找出图片边界
  • 设计模式(笔记)优先使用对象组合而不是类继承

    优先使用对象组合而不是类继承 文章内容参考自 http www hautelooktech com 2013 02 05 design principle favor composition over inheritance agilede
  • hdu 1059 Dividing

    Problem acm hdu edu cn showproblem php pid 1059 题意 6 种宝石 价值分别是 1 到 6 分别给出 6 种宝石的数量 问能不能分成等价值的两堆 分析 多重背包 主要是记录下多重背包的写法 对每
  • 无向图-邻接链表的深度优先遍历-DFS

    一 DFS思想 本算法以无向网为例 存储方式采用邻接链表1 将该网以邻接链表的方式存储 2 选取A点为起始点 访问此顶点 用一个visit的bool型数组记录访问状态 false表示未被访问 true表示已访问 3 从A的未被访问的邻接点出