总代码:
#include<iostream>
using namespace std;
template<class T>
class graph{
public:
virtual int numberOfVertices() const=0;//返回顶点数
virtual int numberOfEdges() const=0;// 返回边数
virtual bool existsEdge(int, int) const=0;//如果 i,j 边存在 返回true
virtual void insertEdge(edge<T> *) =0;// 插入边i j
virtual void eraseEdge(int ,int )=0;// 删除边
virtual int inDegree(int ) const =0;// 返回该点 的入度
virtual int outDegree(int ) const =0;// 返回 出度
virtual bool directed() const=0;// 有向图返回TRUE
virtual bool weighted() const-0;// 加权 返回TRUE
virtual vertexIterator<T>* iterator(int) =0;// 访问指定顶点的相邻顶点 迭代器
};
template<class T>
class edge{
public:
virtual int vertex1();//返回第一个顶点
virtual int vertex2();// 返回第二个
virtual T weight();// 返回权
};
template<class T>
class vertexIterator{
public:
virtual int next() =0;// 配合 iterator 使用
virtual int next(T&) =0;
};
概念:
顶点/边:
有/无向边:
临接:
加权图/网:
简单路径:
长度:
树/生成树:
二分图:
度:
习题:
16.1
第一个是 因为要是简单路径:不能有重复顶点,且顶点之间不能跳跃(必须要有边)
16.2
5) 4 1
4 521
456321
16.3
自己画,至少两个顶点就行
16.4
比如 127561 注意除头尾 不要有重复节点
16.5
一样的 比如 32563
16.6
就是根据图去掉一些边(顶点不变) 使其不产生回路就行 ,且是联通的
生成树: 有n-1条边
16.7
三位
首先jack是必选的 因为只有其能覆盖周日
还剩下4个顶点 至少两人
16.8
教务分配系统
工程任务分配
16.9
邻接于==关联于 == 出度== 指向的一方
邻接至==关联至==入度== 被指向的一方
16.10
1)
因为不是有向,两个顶点之间可以有两条边
-- 一共可以有n(n-1)*2 度
-- 同特性16.1 可证明(1)
2)
一条有向边 必有出度和入度,所以必相等
16.11
证明图中度数为奇数的结点必定是偶数个
给定一个无向图图G=(V,E),其中V表示顶点集合,E表示边集合.则有握手定理成立,即图中所有顶点的度数之和等于两倍的边数,换句话来说,所有顶点的度数之和一定是偶数.所以如果图中存在度数是奇数的顶点,那么为了保证所有点的度数之和为偶数,只能让这样的奇数度的点为偶数个.
16.12
连通图 ,如果有一个度数不为1 则一定能连回来
15.13
因为是环路,少其中一边也是联通的 ;
15.14
1) 生成树就是这么定义的
2) 就像连接n个顶点至少需要n-1条边一样
15.15
1)
因为要形成回路
有n个顶点的强连通图最少有n条边。
图像为n个顶点围成一个圈,且圈上各边方向一致,即均为顺时针或者逆时针,此时有n条边。
2)
反过来一样,至少要n条边才能形成环
---------------------------------------
16.16-20
16.21
不储存对角线,且是对称 : 一共需要 (n^2-n)/2
映射到一维数组为: 【[(i-1)*(i-2)]/2 +j】
16.22
【[i*(i-1)]/2 +j】
23:
遍历所有二维数组 ++
24
都是O(2m) m为当前顶点的度
25
遍历链表呗
26
与24一样
27
O(m) 只需要删除一边,因为不是对称的
28
29
30-31
自己画 一样的,对于weight有一些区别罢了
32
由于是有向图 输入一边 即可
33
直接复制数组里的所有内容即可
34
临接链表 ,肯定是线性的
35
一样的 多一个域
36
查询此位置,然后替换元素,insert就是不存在此元素便插入?
37-40
一样的,本质就是数组和链表以及元素之间的关系
41 -42
43
类似于等价类? 都是寻找一个未遍历的节点
44
一样的,只是判断是否已经标记和如何便利的区别 说到底还是实现方法的区别
肯定快很多
45
类似于层序遍历,和前序。 深度搜索时是往下按层搜索的
46-47
48-49
遍历过程中 找到一条边则存在数组中pair<i,j> 应该为n-1条
50
遍历过程中 碰到一个已经标记的则表示有环路
51
判断二分图的常见方法是染色法:用两种颜色,对所有顶点逐个染色,且相邻顶点染不同的颜色,如果发现相邻顶点染了同一种颜色,就认为此图不为二分图。 当所有顶点都被染色,且没有发现同色的相邻顶点,就退出
52-53
(原创)有向图的传递闭包问题_weixin_30312563的博客-CSDN博客
要点是如何证明是联通的就行
总结:
图的表示方式{
a 邻接矩阵:
可采用数组映射方式
对于无向图 由于其实对称的,可以对角线及以上都不用
加权图:元素是weight的类型而不是bool
b 领接链表:
用链表数组方式来表示
无权图:一个顶点域,一个指针域
加权: 增加一个weight域
c 邻接数组:
邻接的不是链表而是数组-- 不规则数组
对于加权:数组类型是pair<weight,v>
}
图的遍历:「
BFS(breadth first search) :广度优先
利用标志数组,和一个queue ,类似于树的中序遍历,迭代完成
DFS(depth first search):深度优先
利用标志数组,标记第一个相邻顶点,递归来完成,
」
应用:
1 寻找一条路径:
额外用一个数组来记录路径
利用BFS: 找到的是最短路径 DFS : 不一定是最短路径
2 连通图及其构成
类似于等价类? 划分集合
3 生成树
利用DFS 生成的树 : 广度优先生成树
利用DFS 生成的树:深度优先生成树
基本数据结构都学完了,接下来应该算法部分了?