快要面临实习了,最近打算专攻一些算法,这篇主要回顾一下图的基本算法,以及基本的的数据结构。
简介
本文主要回顾本科所学的关于图的一些数据结构和基本算法,图在实际问题中应用很广泛,是一种非常重要的数据结构。第一部分叙述图的定义以及基本表示形式,第二部分叙述关于图的一些常用算法。
图的描述
图的定义
图是顶点的非空集合和顶点之间边的非空集合组成的,常用**G(V,E)**表示,其中G表示一个图,V代表图G中顶点的集合,E表示图中边的集合。
图主要分为两类:一种是有向图,一种是无向图。其中有向图是顶点到顶点之间的边是有方向的,而无向图说明顶点间的边是不区分方向的。还有一种特殊的图称为网:顶点间的每条边有一个权重值。
图的基本表示
邻接矩阵
邻接矩阵可以非常简单明了的描述一个图。其主要思想是用一个二维数组描述图中顶点间的关系。它也可以很方便的描述网,其中无向图的邻接矩阵是沿对角线对称的。图的邻接矩阵的C语言描述如下所示:
1 |
|
其中邻接表的初始化代码如下:
1 | void create_graph( GraphAdjList * G ) { |
逆邻接表
在无向图的邻接表中,顶点V的度恰为顶点V对应的第i个链表中的节点数;
而在有向图中,第i个链表中的结点个数只是顶点V的出度,为求入度,必须遍历整个邻接表。有时,为了便于确定顶点的入度或以顶点V为头的弧,可以再建立一个有向图的逆邻接表,**即对每个顶点V建立一个链接以V为头的弧的链表。**其存储结构与邻接表相同。
十字链表
十字链表是有向图的一种存储方法,它实际上是邻接表与逆邻接表的结合。即把每一条边的边结点分别组织到以弧尾顶点为头结点的链表和以弧头顶点为头顶点的链表中。这里有向边称之为弧,弧头为:有向边的起始点;弧尾为:有向边的末尾节点。其C语言描述如下:
1 | typedef struct EdgeNode { |
十字链表的初始化比较麻烦,但实现不难。其过程如下:
1 | void create_graph( OLGraph * G ) { |
广度优先遍历BFS
可以采用队列数据结构,就像二叉树的层次遍历,其C语言描述如下:
1 | /* |
最后
上面是图的基本数据结构以及基本算法,在这个时候,整体梳理一下。下一篇在准备写图的一些常用算法,比如求最小生成树,最短路径等等…
上面参考了网上不少博主的文章,在此表示感谢_
参考:
[1] 大话数据结构-图
[2] C语言中文网
[3] 有向图的十字链表操作
[4] 图的遍历之深度优先搜索和广度优先