专题讨论3 - 图
数据结构-专题讨论3-图
| 项目 | |
|---|---|
| 讨论题目 | 校园网站地图绘制 |
| 参与者 | 豆芽菜、蜡笔小晞 |
一、说在前面
-
集美大学有很多网站,包括集美大学主页,还有各个学院与教务处等管理部门的网站。这些网站一般通过 超链接 实现相互连接,是一种 图 的关系。基于这种逻辑结构,我们决定从 拓扑结构 出发,较深入的学习和掌握图的概念与实际应用。
-
拓扑结构简述(此处内容参考借鉴ai):
1)简要定义: 是一种抛开物理位置、距离、形态,仅描述节点与连接边之间逻辑关系的网络架构。
2)基础概念(网站网络):
节点: 单个网站,是网络基本单元。
边: 网站间的超链接(单向 / 双向跳转)。
度: 一个节点的连接数。
出度: 该网站向外指向其他站点的链接数;
入度: 其他网站指向本站的链接数。
3)网络拓扑结构的核心特点:
节点数: 规模极大、动态增长,全网站点数量庞大且持续新增 / 消亡。
边数: 远小于全连接网络(每两个网站之间均互相添加超链接),链接分布极不均匀,整体稀疏。
节点度(核心特征)
服从幂律分布: 极少数头部站点(门户、搜索引擎)入度 / 出度极高(核心枢纽);绝大多数中小网站度值很低。
存在大量孤立 / 低链接节点(个人小站、小众站点) -
本次讨论可能涉及的网站如下:


二、关于绘制网站拓扑图的算法
1、网站拓扑图应该用什么样的存储结构?
- 结合网站拓扑(节点(被访问对象) = 页面 / 接口,边(具体操作) = 访问 / 跳转 / 链路)场景,用图结构实现。
- 学校网站拓扑是有向图(页面跳转、接口调用是有向边),优先选邻接表(网站节点数量多,边数相对稀疏,邻接表效率更高,适合稀疏图绘制)。
2、绘制拓扑图的伪代码
基于邻接表拓扑的结构定义
// 1. 边节点结构体:保存相邻节点
typedef struct EdgeNode {
int id; // 相邻节点的编号
struct EdgeNode *next; // 指向下一个邻接节点
} EdgeNode;
// 2. 表头节点结构体:对应网站每一个节点(页面)
typedef struct WebNode {
char name[20]; // 节点名称:首页、子网站等
EdgeNode *firstEdge;// 指向第一个邻接边节点
} WebNode;
// 3. 整个图(邻接表)
typedef struct {
WebNode HeadList[MAX_NODE]; // 表头数组
int nodeNum;
int edgeNum;
} MyGraph;
visited[] : 布尔数组,标记节点是否已绘制(防止重复绘制)
DFS实现绘制
viod DFS_Draw(int u)
{
DrawNode(u)
visited[u] = true
取出当前节点u第一条邻接边*p
//遍历图G
while(p不为空)
v = p.id
DrawEdge(u, v)
如果 节点v没有记录
DFS_Draw(v)
// 访问下一个邻接节点
p = p.next
}
BFS实现绘制
viod BFS_Draw(int start)
{
创建空队列 q
起点入队 + 标记已绘制
while 队列不为空
{
// 队首节点出队
a = q.DeQueue()
// 绘制当前节点
DrawNode(a)
取出当前节点u第一条邻接边*p
while(队列不为空)
{
b= p.id
DrawEdge(a, b)
如果a没有入队,a=q.EnQueue()
并标记visited=true
}
p = p.next
}
}
- 时间复杂度
DFS和BFS都只处理一次所有的边和节点,所以时间复杂度均为O(n+e)
三、“从一个点出发到达其他节点”的本质
【图的遍历】
- 从「网站首页」出发,依次访问列表页、详情页、个人中心…… 就是典型的图遍历。
- 深度优先 DFS:一条路走到头,走不通再回头走另一条路(递归)
广度优先 BFS:先走完起点身边所有相邻节点,再走下一层节点,一圈一圈向外扩散(队列)
【连通性的判断】
- 判断:从起点出发,能不能走到另一个节点。
- 连通图:从任意一个节点出发,都能到达图里所有其他节点(一般可正常访问的网站)。
- 非连通图:图被分成多个 “独立片区”,片区之间没有链路,从一个片区的节点,永远到不了另一个片区(嗯,就是若干毫无关系的网站)
四、总结
- 网站拓扑属于稀疏图,邻接表搭配 DFS/BFS 效率远高于邻接矩阵;若使用邻接矩阵存储,时间复杂度会退化为(O(n^2)),节点越多差距越明显。
浙公网安备 33010602011771号