数据结构学习笔记——第八章“图”1.1

2023/5/16 最近在学习数据结构,感觉知识如同流水,学了就忘。所以开此博客,来记录学习笔记。如果有错误的地方也烦请大佬指正。(就从最近在学的一章开始,前面的慢慢补


基础概念的思维导图


图的存储结构

下面用伪代码进行实现

一、邻接矩阵:

  1. 存储空间O(n2),适用于稠密图
  2. 无向图是对称矩阵,压缩存储
  3. 需要提取边权值通常采用邻接矩阵存储结构O(n2)
#define MAXV[最大顶点个数]
#define INF 32767
typedef struct
{
    int no; //顶点的编号
    InfoType info; //顶点其他信息
}VertexType; //顶点的类型
typedef struct
{
    int edges[MAXV][MAXV]; //邻接矩阵数组
    int n,e; //顶点个数,边数
    VertexType vexsp[MAXV]; //顶点的信息
}MatGraph; //图邻接矩阵类型

Question1:INF 32767 为什么代表 ∞

个人理解:

整数的最大值:

16位:0111111111111111(15个1) 十六进制:0X3FFF 十进制:32767

32位:0(31个1) 十六进制:0X7F×7

网上查找:

16位 int 类型 取值范围 -32768~32767

32位 int 类型 取值范围 -2147483648~2147483647


二、邻接表:

头结点(data,firstarc)

边结点(adjvex,nextarc,weight)

  1. 无向图(n顶点,e边):n头结点,2e边结点
  2. 有向图:n头结点,e边结点
  3. 提取顶点的所有邻接点采用邻接表存储结构
typedef struct ANode
{ 
    int adjvex; //边结点邻接点编号
    struct ANode* nextarc; //指向下一边的指针
    int weight; //权之类的
}ArcNode; //边结点
typedef struct Vnode
{
    InfoType info; //顶点其他信息
    AreNode *firstarc; //指向边结点
}VNode; //头结点
typedef struct
{
    VNode adjlist[MAXV]; //邻接表的头结点数组
    int n,e; //顶点数,边数
}AdjGraph;  //图邻接表类型


图的基本运算设计(邻接表)

1.创建图

void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)

思路:

  1. 为邻接表分配存储空间
  2. 头结点的firstarc置空
  3. 在邻接矩阵数组中遍历,找到有连通的路线。创立边结点(创立结点p):adjvex=j,weight为A[i][j],头插法插入第i个单链表中。
  4. n,e赋值

2.输出图

void DisAdj(AdjGragh *G)
  1. 定义一个边结点指针p
  2. p指向头结点的指向第一个边结点,输出i
  3. p不为空->输出边结点内信息
  4. p移动
  5. 最后一个头结点循环结束,输出空的符号

3.销毁图

void DestroyAdj(AdjGraph *&G)
  1. 定义,前驱指针pre,和指针p
  2. 一重循环
  3. pre指向头结点的指向第一个边结点->非空(二重循环)->让p指向后面一个边结点
  4. 销毁pre,pre移动到p,p移动到下一个
  5. 释放p
  6. 释放头结点

三、其他存储方式

1.十字链表(有向图)

头结点(data,firstin,firstout)

                         入度      出度

边结点(tailvex,headvex,hlink,tlink,weight)

             起点        终点         相同起点下一个边结点   相同终点下一个边结点

2.邻接多重表(无向图)

头结点(data,firstarc)

边结点(mark,i,ilink,j,jlink,weight)

            是否被搜索过   i,j 顶点    ilink(jlink) 下一依附于 i ( j )的结点

图的遍历

visited 数组 进行标记 0:未访问 1:已访问

深度优先遍历(DFS)(把一条路走到底)

递归思路:从首个开始,第一个,第一个开始,如果已经遍历过,就下一个。

邻接表O(n+e)

邻接矩阵O(n2)

//关键代码:v是起点,u是终点
p=G->adjlist[v].firstarc;
while(p!=NULL)
{
    if(visited[p->adjvex]==0) //还没走过
    {
        DFS(G,p->adjvex);
    }
    p=p->nextarc;
}

广度优先遍历(BFS)(所有岔道路口都检查,遍历一遍)

借用队列

队列不为空,查找队内元素邻接点,未被访问则标记加进队,继续找下一个邻接点。

邻接表O(n+e)

邻接矩阵O(n2)

非连通图遍历

需要在额外,查找是否所有元素被访问,没有就重复DFS/BFS算法。

关于图遍历算法的运用,暂时个人理解:

(1)DFS 用于找简单路径,不重复的路

(2)BFS 用于找最短路径

图的遍历的应用

一、DFS

(1)判断是否有简单路径: 遍历后,if(v==u) true

(2)输出一条简单路径:在(1)的基础上,数组path存储每条路线,if(v==u) 输出path。可以设置一个

(3)所有简单路径:在(2)的基础上,最后当p后面为NULL时候,visited[u]=0,使该顶点重新使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值