来源:互联网 发布:适合宅男玩的游戏知乎 编辑:程序博客网 时间:2024/05/16 00:59

基础理论

  图的基本定义 : 二元组 , 即结点和边( 弧 ) G = ( V, {E} )

  有向图, 弧尾 --> 弧头

  无向图, 边

  无向完全图  n个结点 , 1/2n(n-1) 边, 就是任意两个结点都有边。

  带权的图 , 这的权类似赫夫曼树的权.

  子图 : G' = ( v', { E' } ) , v' 是v的子集, E' 是E的子集

  邻接点 ( 互为) 两个结点有边

  顶点v的 : 无向图 相连的边 , 有向图 度 = 入度 + 出度

  图的存储方法 :

  1.数组存储表示( 邻接矩阵 )

/* 图 数组邻接矩阵 */typedef struct ArcCell {/* 边的结构 */VRType arcs;/* 相连 1, 不相连 0*/InfoType *info;/* 边本身可能的信息 */} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VER_TEX_NUM];typedef struct {/* 图的结构 */VertexType vex[MAX_VERTEX_NUM];/* 本身顶点存储的信息 */AdjMatrix arcs;/* 顶点之间关系 */int vexnum, arcnum;/* 顶点数和弧数 */GraphKind kind;/* 图的种类标志 */} MGraph;
说白了,就是用两个数组来存放图,一个是图的关系,即顶点之间的连接关系。另一个数组用来存放顶点内容。

2。邻接表

是图的一种链式存储结构,在邻接表中,对图中每个顶点建立一个单链表,第 i 个单链表中的节点表示依附于顶点vi 的边( 对有向图是以顶点vi为尾的弧 )

 

typedef struct ArcNode {/* 存储边的情况 */int adjvex;/* 指示顶点在该顶点数组中的下标 */struct ArcNode *nextarc;/* 跟此顶点相连的边 */Infotype *info;/* 记录弧本身的信息,如权值 */} ArcNode;typedef struc VNode {/* 顶点结构 */VertexType data;/* 顶点信息 */ArcNode *firstarc;/* 第一条弧 */} VNode, AdjList[MAX_VERTEX_NUM];typedef struct {/* 图的结构 */AdjList vertices;/* 图中顶点 */int vexnum, arcnum;/* 顶点数和弧数 */in kind;/* 图的标志 */} ALGraph;

3。十字链表存储法 ( 有向图 )

typedef struct Arcbox {/* 弧的存储 */int tailvex, headvex;/* 弧头, 弧尾节点在顶点数组中的下标 */struct Arcbox *hlink, *tlink;/* 弧头,弧尾相同的链域 */InfoType *info;/* 弧本身信息 */} Arcbox;typedef struct VexNode {/* 顶点存储 */VertexType data;/* 顶点信息 */Arcbox *firstin, *firstout;/* 第一个入弧,第一个出弧 */} VexNode;typedef struct {/* 图的存储 */VexNode xlist[MAX_VERTEX_NUM];/* 顶点数组 */int vexnum, arcnum;/* 顶点数,弧数 */} OLGraph;

4。邻接多重表 ( 无向图 ) ( 有点蒙 )

typedef struct EBox { /* 弧的存储 */VisitIfmark;/* 标记是否被访问过 */int ivex, jvex;/* 依附此弧的两个顶点在数组中的下标 */struct EBox *ilink, *jlink;/* 分别指向这两个顶点的下一条边 */infoTYpe *info;/* 弧本身的信息 */} EBox;typedef struct VexNode {/* 顶点存储 */VertexType data;/* 顶点信息 */EBox *firstedge;/* 第一个边 */} VexBox;typedef struct {/* 图的存储 */vexBox adjmulist[MAX_VERTEX_NUM];/* 顶点数组 */int vexnum, arcnum;/* 顶点数,弧数 */} AMLGraph;

  图的遍历 ( 深度优先 , 广度优先 )

深度优先 : 类似于树饿先根遍历,根左右, 即访问到一个节点后,访问子节点a , 然后继续访问子节点的节点,而不是横向访问 a 的兄弟。

广度优先: 有点类似按层次访问,比如先访问节点a , 然后访问其全部子节点,完毕后,即,兄弟节点肯定要比子节点先被访问到.

例如 :


深度优先 : v1 -> v2 -> v4 -> v8 -> v5 -> v3 -> v6 -> v7

广度优先 : v1 -> v2 -> v3 -> v4 -> v5 -> v6 -> v7 -> v8