青少年人工智能编程科普教育机构-凡恩机器人联盟

手机站
当前位置: 主页 > C++ > 正文

少儿编程C++基础:图的表示方式-成都凡恩机器人联盟

来源:成都凡恩
发布人:青少年编程教育
时间:2024-11-12 15:45:13

图的概念

1、基本术语

图是由节点以及连接这些节点边组成。

2、应用举例

2.1社交网络

在社交网络中所有的用户构成了多对多的朋友关系网,这个关系网就是图:每个人都是图中的节点,互相认识的人之间通过边进行联系。如下图:

在有些图中,节点之间的并不是完全对称的,比如在微信中:A和B互相加了好友,但A单方面删除了B,这样A的好友列表中已经没有了B,但B的好友列表中依然有A,这样图中节点之间的边就有了方向的区分,即为有向图。

在QQ的好友关系中,当A删除了B的时候B的好友列表里也就同步没有了A,即节点之间的边没有方向的区分,即为无向图。

2.2、路线图

在图中,可以给边分配一个数值叫权重,比如在一个路线图中,A市到B市的距离是2km,即从A节点出发到B节点的边的权重是2km,如下图所示:

图的表示方式

1、邻接矩阵

邻接矩阵是表示图中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵的row和col表示的是0-n-1的n个点。

对包含n个节点的图,可以用二维数组(矩阵)来表示节点之间两两的连接关系,如下图:

vector<vector<int>> edges;//用二纬数组表示各点之间两两的连通关系
int val = edges[i][j];//表示从节点i到节点j的边,0则表示非连通,有权重时也可以表示权重值

2、邻接列表

邻接矩阵可以方便的得到一个节点到另个节点的关联关系,但是邻接矩阵给每个节点都分配n个边的空间,但实际有许多变是不存在的,会造成空间的浪费。

邻接列表只关心存在的边,不关心不存在的边,如下图所示:

vector<vector<int>> edges(n);//无权图时,用n个一维数组构成的vector来存储邻接列表
vector<int> n_edge = edges[i];//存储节点i可以直接访问的节点列表


vector<vector<vector<int>>>edges(n);//无权图时,用n个二维数组构成的vector来存储邻接列表
edges[i][j][0];//表示节点i的第j个连通节点编号
edges[i][j][1];//表示节点i到第j个连通节点边的权重

3、边缘列表

边缘列表是具有连接顶点及其权重的边的集合,如下图:



vector<vector<int>> edges;//无权图时,用一系列长度为2的vector构成vector来存储边缘列表
int u = edges[i][0];//第i条边的起点
int v = edges[i][1];//第i条边的终点

vector<vector<int>> edges;//带权图时,用一系列长度为3的vector构成vector来存储边缘列表
int u = edges[i][0];//第i条边的起点
nt v = edges[i][1];//第i条边的终点
int val = edges[i][2];//边 u -> v 的权重

图的应用举例

现在你总共有 n 门课需要选,记为 0 到 n-1。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1
,我们用一个匹配来表示他们: [0,1] 给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。说明: 1.
输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。2. 你可以假定输入的先决条件中没有重复的边。

LeetCode:210.课程表Ⅱ

1、题目分析

要学习一门课程则必须学习完其所有的先决条件课程,即可以用有向图来描述这种依赖关系,节点间的连接关系不对等。

当前可以上的课即为不依赖于任何一门剩下未学习的课的课,即图中入度为0的节点。可以采用BFS进行搜索访问所有节点。

题目中先决条件使用边缘列表来表示图,转换成图的邻接列表后可以方便的获取某个节点可以访问的节点列表、同时记录节点的入度。

2、实现步骤

  • 图的边缘列表转成邻接列表,并记录节点入度

  • 入度为0的节点入队

  • 取出队首u,并将u加入结果数据

  • 将u的所有邻接点的入度减1,更改后入度为0的节点入队

  • 搜索结束后若结果数组的大小等于节点总数则满足要求

3、代码示例

 class Solution {
    public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>> edges(numCourses) ;//邻接列表        
        vector<int> inedg = vector(numCourses,0);//节点的入度        
        vector<int> res;//结果保存
        //由图的边缘列表转换成图的邻接列表,根据u->v,给节点u的邻接点添加v、v的入度加1 
        for(int i = 0;i < prerequisites.size();i++)        
        {            
            edges[prerequisites[i][1]].push_back(prerequisites[i][0]);            
            inedg[prerequisites[i][0]]++;        
        }
        //BFS搜索,所有入度为0的节点依次入队
        queue<int> myqueue;
        for(int i = 0;i < numCourses;i++)
        {
            if(inedg[i] == 0)                
                myqueue.push(i);
        }
        while(!myqueue.empty())
        {
            int u = myqueue.front();myqueue.pop();
            res.push_back(u);
            //删除该节点后,该节点的所有邻接点的入度依次减1,变更后入度为0的节点入队
            for(int i = 0;i < edges[u].size();i++)
            {
                if( --inedg[edges[u][i]] == 0)
                {
                     myqueue.push(edges[u][i]);                   
                }        
            }
        }
        if( res.size() != numCourses)//返回结果和节点数不相等,则无法完成所有课程
            return {};   
        return res;                
    }
}
声明:本站稿件凡恩品牌资讯以外部分类目资讯转载来自于互联网,如有疑义请联系我们删除。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
下一篇:没有了
相关推荐HOT
少儿编程C++基础:前缀和算法(二)
少儿编程C++基础:前缀和算法(二)

前缀和是一个数组的某项下标之前(包括该元素)的所有数组元素的和,前缀和是一种重要的预处理操作,可以降低查询的时间复杂度。本文以 leetcode 中算法题为例子多前缀和算法的应用进行说明前缀和应用举例......详情>>

2024-11-12
少儿编程C++基础:前缀和算法(一)
少儿编程C++基础:前缀和算法(一)

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2, [1,1] 与 [1,1] 为两种不同的......详情>>

2024-11-12
少儿编程C++基础:双指针使用总结(三)
少儿编程C++基础:双指针使用总结(三)

双指针是一种解决问题的技巧或者思维方式,指在访问一个序列中的数据时使用两个指针进行扫描,两个指针可以是同向的,也可以是反向的;我们的关注点可以是这两个指针指向的两个元素本身,也可以是两个指针中间的区域......详情>>

2024-11-12
少儿编程C++基础:双指针总结(一)
少儿编程C++基础:双指针总结(一)

双指针是一种解决问题的技巧或者思维方式,指在访问一个序列中的数据时使用两个指针进行扫描,两个指针可以是同向的,也可以是反向的;我们的关注点可以是这两个指针指向的两个元素本身,也可以是两个指针中间的区域......详情>>

2024-11-12
少儿编程C++基础:双指针的使用总结(二)
少儿编程C++基础:双指针的使用总结(二)

双指针是一种解决问题的技巧或者思维方式,指在访问一个序列中的数据时使用两个指针进行扫描,两个指针可以是同向的,也可以是反向的;我们的关注点可以是这两个指针指向的两个元素本身,也可以是两个指针中间的区域......详情>>

2024-11-12
少儿编程导师
朵朵老师
少儿编程导师
琴琴老师
少儿编程导师
苏老师

赛事资讯

凡恩资讯

政策资讯