学习笔记7——图(C++版)

一、什么是图、为什么要使用图

图是由顶点构成的一种数据结构(边和顶点都存储着数据)。

使用图当然是为了解决编程问题,用广度优先搜索或者深度优先算法来解决。

1.有向图

如图1

2.无向图

如图2

3.连通图

任意两个顶点都有路径,比如图2中,虽然A、C没有直接连通,但是可以A>B>C,A、C间接连通。

4.完全图

如果把图2中A、C,B、D连接起来,就能叫做完全图。注意,就算图1中A、C,B、D连接起来,也不能叫完全图,因为有向图的完全图不仅要有A>B的路径,还要有B>A的路径。

二、图的存储

图1 有向图                                                              图2 无向图

1.邻接矩阵(把顶点和边分开存储)
邻接矩阵的顶点(和哈希表类似)
//A:1  B:2  C:3  D:4
struct Node
{
    int val; //顶点数据
    Node(int x):val(x){}
};

Node*A = Node(1);
Node*B = Node(2);
Node*C = Node(3);
Node*D = Node(4);
邻接矩阵的边

//A:1  B:2  C:3  D:4
struct Map
{
    vector<Node*>v1;  //存放顶点
    vector<vector<int>>matrix;  //存放邻接矩阵
}

//假设存储图1
Map*map;
map->v1.push_back(A);
map->v1.push_back(B);
map->v1.push_back(C);
map->v1.push_back(D);


map->matrix = {{0,1,0,1},
              {0,0,1,0},
              {0,0,0,0},
              {0,0,1,0}};
//假如把二维数组中的1换成我们想要存储的数据,是不是就意味着我们的边也可以存储数据
2.邻接表

邻接表的顶点
//A:1  B:2  C:3  D:4
struct Node
{
    int val; //顶点数据
    Arc* head;  //顶点的出弧链表表头(把所有的出弧连成链表)
    Node(int x):val(x),link(nullptr){}
};

Node*A = Node(1);
Node*B = Node(2);
Node*C = Node(3);
Node*D = Node(4);
邻接表的出弧

a、d称为顶点A的出弧,我们用一个链表来储存。

struct Arc
{
    int val; //出弧数据
    Arc* next;  //指向下一条弧的指针
    Arc(int x):val(x),next(nullptr){}
};

Arc*a = Arc(5);
Arc*b = Arc(6);
Arc*c = Arc(7);
Arc*d = Arc(8);

a->next = d;
A->head = a;  //A顶点的出弧是a、d

B->head = b;  //B的出弧是b

D->head = c;  //D的出弧是c

这样就把出弧存储在顶点中。

接着创建一个存储顶点的顶点数组。

struct Map
{
    vector<Node*>map; //顶点数据,存放顶点
};
3.十字链表

顶点在2的基础上,多了一个入弧(b、c)连接而成的链表。

//A:1  B:2  C:3  D:4
struct Node
{
    int val; //顶点数据
    Arc* head;  //顶点的出弧链表表头(把所有的出弧连成链表)
    Arc* tail;  //顶点的入弧链表表头
    Node(int x):val(x),link(nullptr){}
};

Node*A = Node(1);
Node*B = Node(2);
Node*C = Node(3);
Node*D = Node(4);
4.邻接多重表

这个不是很懂,欢迎大家评论区补充。

三、图的遍历
1.深度优先搜索
2.广度优先搜索
3.最小生成树(把所有点连接起来,并且边的和最小)

n个顶点的连通图的生成树有n-1条边。

普里姆算法
克鲁斯卡尔算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值