【数据结构】图的定义,存储,遍历

这篇具有很好参考价值的文章主要介绍了【数据结构】图的定义,存储,遍历。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🎊专栏【数据结构】

🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。

🎆音乐分享【Dream It Possible】

大一同学小吉,欢迎并且感谢大家指出我的问题🥰

目录

🍔前言

🎁图的定义 

 🏳️‍🌈有向完全图

🏳️‍🌈无向完全图

🎁存储结构

🏳️‍🌈邻接矩阵 

🎈代码

🏳️‍🌈采用邻接矩阵表示法创建无向  网

🎈算法步骤

🎈算法描述

 🏳️‍🌈采用邻接矩阵表示法创建无向  网

🎁图的遍历

 🏳️‍🌈深度优先遍历

🎈算法步骤

🎈算法描述

🎁广度优先遍历

🎈算法步骤

🎈算法描述

🎁附加 

🏳️‍🌈实验题目

🏳️‍🌈代码

🏳️‍🌈运行结果 


 文章来源地址https://www.toymoban.com/news/detail-457249.html

🍔前言

        图是一种比线性表和树更为复杂的数据结构。在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树结构中,数据元素之间有着明显的层次关系,并且每一层中的数据元素可能和下一层中的多个元素(其孩子结点)相关,但只能和上一层中一个元素(其双亲结点)相关;而在图结构中,结点之间的关系可以是任意的,图中任意两个数据元素都可能相关。由此,图的应用极为广泛,已渗入诸如物理、化学、通信、计算机,以及数学等领域。在离散数学中,图论是专门研究图的性质的数学分支,而在数据结构中,则应用图论的知识讨论如何在计算机上实现图的操作,因此本章主要介绍图的存储结构,以及若干图的操作的实现。

🎁图的定义 

        图(Graph)G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集合,这些顶点偶对称为边。V(G)和E(G)通常分别表示图G的顶点集合和边集合,E(G)可以为空集。若E(G)为空,则图G只有顶点而没有边。
        对于图G,若边集E(G)为有向边的集合,则称该图为有向图;若边集E(G)为无向边的集合,则称该图为无向图。
        在有向图中,顶点对<x,y>是有序的,它称为从顶点x到顶点y的一条有向边。因此,<x,y>与1是不同的两条边。顶点对用尖括号括起来,对<x,y>而言,x是有向边的始点,y是有向边的终点。<x,y>也称作一条弧,则x为弧尾,y为弧头。
        在无向图中,顶点对(x,y)是无序的,它称为与顶点x和顶点y相关联的一条边。这条边没有特定的方向,(x,y)与(y,x)是同一条边。为了有别于有向图,无向图的顶点对用一对圆括号括起来。

【数据结构】图的定义,存储,遍历

 🏳️‍🌈有向完全图

有n(n-1)条弧  的图

🏳️‍🌈无向完全图

有n(n-1)/2条边  的图

🎁存储结构

🏳️‍🌈邻接矩阵 

表示顶点之间相邻关系的矩阵,设G(V,E)是具有n个顶点的图,那么G的邻接矩阵有如下性质

(矩阵实在是画不好,绘图能力欠佳,也请大家多多包容🥰) 

【数据结构】图的定义,存储,遍历

 使用邻接矩阵表示图,除了一个用于存储邻接矩阵的二维数组外,还需要一个一维数组来存储顶点信息

🎈代码

//图的 邻接矩阵 存储表示

#define MaxInt 32767     //表示极大值,即 ∞ 
#define MVNum 100        //最大顶点数 
typedef int VerTexType; //设顶点的数据类型为字符型 
typedef int ArcType;     //假设边的权值类型为整型 

typedef struct{
	VerTexType vexs[MVNum];      //顶点表 
	ArcType arcs[MVNum][MVNum];  //邻接矩阵
	int vexnum,arcnum;           //图的当前点数和边数 
}AMGraph; 

🏳️‍🌈采用邻接矩阵表示法创建无向  网

🎈算法步骤

1.输入总顶点数和总边数

2.依次输入点的信息并将其存入顶点表中

3.初始化邻接矩阵,每个权值初始化为最大值

4.构造邻接矩阵,依次输入每条边依附的顶点以及其权值,确定两个顶点在图中的位置之后,使相应边赋予相应的权值,同时使其对称边赋予相同的权值

🎈算法描述

int located(AMGraph &G, VerTexType v)
{
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vexs[i] == v) {
            return i;
        }
    }
    return -1; // 未找到,返回 -1
}


int Create(AMGraph &G)
{
	cin>>G.vexnum>>G.arcnum;
	for(i=0;i<G.vexnum;i++)
	{
		cin>>G.vexs[i];
	}
	for(i=0;i<G.vexnum;i++)
	{
		for(j=0;j<G.vexnum;j++)
		{
			G.arcs[i][j]=MaxInt;
		}
	}
	for(int k=0;k<G.arcnum;k++)
	{
		cin>>v1>>v2>>w;
		i=located(G,v1);
		j=located(G,v2);
		G.arcs[i][j]=w;
		G.arcs[j][i]=G.arcs[i][j];
	}
	return 1;
}

 🏳️‍🌈采用邻接矩阵表示法创建无向  网

进行两处改动即可

1.初始化邻接矩阵时,把边的权值初始化为0

2.构造邻接矩阵时,把权值w修改为1即可

🎁图的遍历

图的遍历也是从图的某一顶点出发,按照某种方法对图的所有顶点进行访问且访问一次

实质:找每个节点的邻接点

 🏳️‍🌈深度优先遍历

深度优先搜索(DepthFirst Search, DFS)遍历类似于树的先序遍历,是树的先序遍历的推广。

🎈算法步骤

(1)从图中某个顶点v出发, 访问v。
(2)找出刚访问过的顶点的第一个未被访问的邻接点, 访问该顶点。 以该顶点为新顶点,重
复此步骤, 直至刚访问过的顶点没有未被访问的邻接点为止。
(3)返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的
邻接点, 访问该顶点。
(4)重复步骤 (2) 和(3), 直至图中所有顶点都被访问过,搜索结束
 
【数据结构】图的定义,存储,遍历

 

🎈算法描述

void DFS(AMGraph G, int v)
{
    printf("%d ", G.vexs[v]);     // 访问顶点 v
    visited[v] = true;            // 标记为已访问
    for (int w = 0; w < G.vexnum; w++)
    {
        if (G.arcs[v][w] != MaxInt && !visited[w])
        {
            DFS(G, w);   // 对未访问的邻接顶点递归调用DFS
        }
    }
}

🎁广度优先遍历

🎈算法步骤

(1) 从图中某个顶点v出发,访问v。
(2)依次访问v的各个未曾访问过的邻接点。
(3)分别从这些邻接点出发依次访问它们的邻接点, 并使 “先被访问的顶点的邻接点“ 先于”后被访问的顶点的邻接点” 被访问。重复步骤(3), 直至图中所有已被访问的顶点的邻接点都被
访间到
【数据结构】图的定义,存储,遍历

 

🎈算法描述

void BFS(AMGraph G, int v)
{
    int front = 0, rear = 0;
    int queue[MVNum];     // 定义队列
    printf("%d ", G.vexs[v]);
    visited[v] = true;
    queue[rear++] = v;    // 将顶点 v 入队
    while (front != rear)
    {
        int k = queue[front++];   // 出队一个顶点 k
        for (int w = 0; w < G.vexnum; w++)
        {
            if (G.arcs[k][w] != MaxInt && !visited[w])
            {
                printf("%d ", G.vexs[w]);     // 访问顶点 w
                visited[w] = true;
                queue[rear++] = w;           // 将顶点 w 入队
            }
        }
    }
}

🎁附加 

🏳️‍🌈实验题目

【数据结构】图的定义,存储,遍历

 

1.使用邻接矩阵的方式存储上边无向图;

2.以矩阵的形式输出无向图

3.在邻接矩阵的基础上实现深度优先遍历和广度优先遍历。

🏳️‍🌈代码

/*
6 6
1 2 3 4 5 6
1 2 1
2 5 1
5 3 1
3 1 1
1 4 1
4 6 1
*/

#include<iostream>
using namespace std;

#define MaxInt 32767     //表示极大值,即 ∞ 
#define MVNum 100        //最大顶点数 
typedef int VerTexType; //设顶点的数据类型为字符型 
typedef int ArcType;     //假设边的权值类型为整型 

typedef struct{
	VerTexType vexs[MVNum];      //顶点表 
	ArcType arcs[MVNum][MVNum];  //邻接矩阵
	int vexnum,arcnum;           //图的当前点数和边数 
}AMGraph; //Adjacency Matrix Graph 

int v1,v2,i,j,k,w;

int located(AMGraph &G, VerTexType v)
{
    for (int i = 0; i < G.vexnum; i++) {
        if (G.vexs[i] == v) {
            return i;
        }
    }
    return -1; // 未找到,返回 -1
}


int Create(AMGraph &G)
{
	cin>>G.vexnum>>G.arcnum;
	for(i=0;i<G.vexnum;i++)
	{
		cin>>G.vexs[i];
	}
	for(i=0;i<G.vexnum;i++)
	{
		for(j=0;j<G.vexnum;j++)
		{
			G.arcs[i][j]=MaxInt;
		}
	} 
	for(int k=0;k<G.arcnum;k++)
	{
		cin>>v1>>v2>>w;
		i=located(G,v1);
		j=located(G,v2);
		G.arcs[i][j]=w;
		G.arcs[j][i]=G.arcs[i][j];
	}
	return 1;
}

bool visited[MVNum];

// 深度优先遍历
void DFS(AMGraph G, int v)
{
    printf("%d ", G.vexs[v]);     // 访问顶点 v
    visited[v] = true;            // 标记为已访问
    for (int w = 0; w < G.vexnum; w++)
    {
        if (G.arcs[v][w] != MaxInt && !visited[w])
        {
            DFS(G, w);   // 对未访问的邻接顶点递归调用DFS
        }
    }
}

// 广度优先遍历
void BFS(AMGraph G, int v)
{
    int front = 0, rear = 0;
    int queue[MVNum];     // 定义队列
    printf("%d ", G.vexs[v]);
    visited[v] = true;
    queue[rear++] = v;    // 将顶点 v 入队
    while (front != rear)
    {
        int k = queue[front++];   // 出队一个顶点 k
        for (int w = 0; w < G.vexnum; w++)
        {
            if (G.arcs[k][w] != MaxInt && !visited[w])
            {
                printf("%d ", G.vexs[w]);     // 访问顶点 w
                visited[w] = true;
                queue[rear++] = w;           // 将顶点 w 入队
            }
        }
    }
}

int main()
{
    AMGraph G;
    Create(G);
    printf("存储成功\n");

    // 输出邻接矩阵
    for (int i = 0; i < G.vexnum; i++)
    {
        for (int j = 0; j < G.vexnum; j++)
        {
            if (G.arcs[i][j] == MaxInt)
            {
                printf("∞ ");
            }
            else
            {
                printf("%d ", G.arcs[i][j]);
            }
        }
        printf("\n");
    }

    // 初始化访问标记数组
    for (int i = 0; i < G.vexnum; i++)
    {
        visited[i] = false;
    }

    printf("深度优先遍历: ");
    for (int i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            DFS(G, i);
        }
    }
    printf("\n");

    // 重置访问标记数组
    for (int i = 0; i < G.vexnum; i++)
    {
        visited[i] = false;
    }

    printf("广度优先遍历: ");
    for (int i = 0; i < G.vexnum; i++)
    {
        if (!visited[i])
        {
            BFS(G, i);
        }
    }
    printf("\n");

    return 0;
}

🏳️‍🌈运行结果 

【数据结构】图的定义,存储,遍历

🥰如果大家有不明白的地方,或者文章有问题,欢迎大家在评论区讨论,指正🥰   

 

到了这里,关于【数据结构】图的定义,存储,遍历的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图的数据结构,系统学习图的基本概念、定义和建立,学会邻接矩阵、邻接表以及实现六度空间案例,遍历图的方式——广度、深度访问

    图 :G = (V,E) Graph = (Vertex, Edge) V:顶点(数据元素)的有穷非空集合; E:边的有穷集合。 有向图 :每条边都是有方向的     无向图 :每条边都是无方向的   完全图 :任意两点之间都有一条边相连    无向完全图:n个顶点,n(n-1)/2条边 无向完全图:n个顶点,n(n-1)条边 稀疏

    2023年04月22日
    浏览(49)
  • 【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

    一个二叉树是一个有穷的结点集合。 它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。 二叉树可具有以下5种形态。 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2 i − 1 , i ≥ 1 i geq 1 i ≥ 1 每层最大结点可以对应完美二叉树(满二叉树),其所有分支结

    2024年02月20日
    浏览(45)
  • 数据结构 | 图的遍历

    使用邻接矩阵法存储图的信息,其中 一维矩阵 Vexs[] 存储节点信息 二维矩阵 Edges[][] 存储边的信息 一维矩阵 visited[] 记录当前节点是否被访问过,用于后面的遍历 本文所使用的图的结构如下: 对应的 Vexs[] 为:A,B,C,D,E,F(对应的数组下标从0到5) 对应的 Edges[][] 如下: 图的

    2024年02月04日
    浏览(41)
  • 数据结构--5.3图的遍历(广度优先遍历)

    广度优先遍历:         广度优先遍历(BreadthFirstSearch),又称为广度优先搜索,简称BFS。 要实现对图的广度遍历,我们可以利用队列来实现。  (参考队列)(上述为结构)

    2024年02月10日
    浏览(47)
  • 【数据结构】图的创建与遍历

    图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。 线性表 :线性关系,由直接前驱和直接后继组成。 树 :层次关系,由父结点和孩子结点组成,每个结点最多有一个父结点(根

    2023年04月22日
    浏览(49)
  • 【数据结构】图的广度优先遍历

    广度优先遍历,类似于树的层次遍历,又是熟悉的队列实现。首先将第一个顶点添加到队列中,然后讲该顶点的所有邻接顶点都加入队列中,再将该顶点输出。如此重复直到遍历完整个图。 Q:队列,用于存放顶点。 front,rear:队头和队尾指针,用于入队和出队。 p:工作指针,用

    2024年02月05日
    浏览(49)
  • 数据结构 第六章 图——图的遍历

    在前面我们知道,树是一种非线性结构,为了方便它在计算机中的存储,对树进行遍历使它线性化。 而图同样也是一种非线性结构,但是图又是一种不同于树的多对多结构,所以在前面我们将其转换为了多个一对多的结构来描述它的存储结构。 图的遍历同树类似,也是从某

    2024年02月08日
    浏览(46)
  • 大话数据结构-图的深度优先遍历和广度优先遍历

      图的遍历分为深度优先遍历和广度优先遍历两种。   深度优先遍历(Depth First Search),也称为深度优先搜索,简称DFS,深度优先遍历,是指从某一个顶点开始,按照一定的规则,访问并记录下一个未访问顶点。对于非连通图,则是按连通分量,采用同一规则进行深度优

    2024年02月04日
    浏览(58)
  • (超详细)C++图的深度优先遍历、广度优先遍历(数据结构)

            根据下图,编写代码实现图的深度优先遍历和广度优先遍历。          按照英文字母顺序,以邻接表为存储结构,实现图的深度优先和广度优先遍历。遍历的顺序从顶点a开始。 以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。   (1)从顶点a,

    2024年02月08日
    浏览(61)
  • 《数据结构》实验报告六:图的表示与遍历

    1、掌握图的 邻接矩阵 和 邻接表 表示 2、掌握图的 深度优先 和 广度优先 搜索方法 3、理解 图的应用 方法 说明以下概念 1、深度优先搜索遍历:        一种图的遍历方式:从图中 任意一个 起始顶点 V 出发,接着访问它的任意一个 邻接顶点 W1 ;再从 W1 出发,访问与 W1

    2024年02月06日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包