讲解视频
图
定义
抽象数据类型
常用术语
无向图、有向图
连通 、路径、回路、连通图
连通分量
强连通、强连通图、强连通分量
图的表示方法
邻接矩阵
简化表示
优点
缺点
代码
#define MaxVertexNum 100
#define INFINITY 65535
typedef int Vertex
;
typedef int WeightType
;
typedef char DataType
;
typedef struct ENode
*PtrToENode
;
struct ENode
{
Vertex V1
, V2
;
WeightType Weight
;
};
typedef PtrToENode Edge
;
typedef struct GNode
*PtrToGNode
;
struct GNode
{
int Nv
;
int Ne
;
WeightType G
[MaxVertexNum
][MaxVertexNum
];
DataType Data
[MaxVertexNum
];
};
typedef PtrToGNode MGraph
;
MGraph
CreateGraph( int VertexNum
)
{
Vertex V
, W
;
MGraph Graph
;
Graph
= (MGraph
)malloc(sizeof(struct GNode
));
Graph
->Nv
= VertexNum
;
Graph
->Ne
= 0;
for (V
=0; V
<Graph
->Nv
; V
++)
for (W
=0; W
<Graph
->Nv
; W
++)
Graph
->G
[V
][W
] = INFINITY
;
return Graph
;
}
void InsertEdge( MGraph Graph
, Edge E
)
{
Graph
->G
[E
->V1
][E
->V2
] = E
->Weight
;
Graph
->G
[E
->V2
][E
->V1
] = E
->Weight
;
}
MGraph
BuildGraph()
{
MGraph Graph
;
Edge E
;
Vertex V
;
int Nv
, i
;
scanf("%d", &Nv
);
Graph
= CreateGraph(Nv
);
scanf("%d", &(Graph
->Ne
));
if ( Graph
->Ne
!= 0 ) {
E
= (Edge
)malloc(sizeof(struct ENode
));
for (i
=0; i
<Graph
->Ne
; i
++) {
scanf("%d %d %d", &E
->V1
, &E
->V2
, &E
->Weight
);
InsertEdge( Graph
, E
);
}
}
for (V
=0; V
<Graph
->Nv
; V
++)
scanf(" %c", &(Graph
->Data
[V
]));
return Graph
;
}
邻接表
优点和缺点
代码
#define MaxVertexNum 100
typedef int Vertex
;
typedef int WeightType
;
typedef char DataType
;
typedef struct ENode
*PtrToENode
;
struct ENode
{
Vertex V1
, V2
;
WeightType Weight
;
};
typedef PtrToENode Edge
;
typedef struct AdjVNode
*PtrToAdjVNode
;
struct AdjVNode
{
Vertex AdjV
;
WeightType Weight
;
PtrToAdjVNode Next
;
};
typedef struct Vnode
{
PtrToAdjVNode FirstEdge
;
DataType Data
;
} AdjList
[MaxVertexNum
];
typedef struct GNode
*PtrToGNode
;
struct GNode
{
int Nv
;
int Ne
;
AdjList G
;
};
typedef PtrToGNode LGraph
;
LGraph
CreateGraph( int VertexNum
)
{
Vertex V
;
LGraph Graph
;
Graph
= (LGraph
)malloc( sizeof(struct GNode
) );
Graph
->Nv
= VertexNum
;
Graph
->Ne
= 0;
for (V
=0; V
<Graph
->Nv
; V
++)
Graph
->G
[V
].FirstEdge
= NULL;
return Graph
;
}
void InsertEdge( LGraph Graph
, Edge E
)
{
PtrToAdjVNode NewNode
;
NewNode
= (PtrToAdjVNode
)malloc(sizeof(struct AdjVNode
));
NewNode
->AdjV
= E
->V2
;
NewNode
->Weight
= E
->Weight
;
NewNode
->Next
= Graph
->G
[E
->V1
].FirstEdge
;
Graph
->G
[E
->V1
].FirstEdge
= NewNode
;
NewNode
= (PtrToAdjVNode
)malloc(sizeof(struct AdjVNode
));
NewNode
->AdjV
= E
->V1
;
NewNode
->Weight
= E
->Weight
;
NewNode
->Next
= Graph
->G
[E
->V2
].FirstEdge
;
Graph
->G
[E
->V2
].FirstEdge
= NewNode
;
}
LGraph
BuildGraph()
{
LGraph Graph
;
Edge E
;
Vertex V
;
int Nv
, i
;
scanf("%d", &Nv
);
Graph
= CreateGraph(Nv
);
scanf("%d", &(Graph
->Ne
));
if ( Graph
->Ne
!= 0 ) {
E
= (Edge
)malloc( sizeof(struct ENode
) );
for (i
=0; i
<Graph
->Ne
; i
++) {
scanf("%d %d %d", &E
->V1
, &E
->V2
, &E
->Weight
);
InsertEdge( Graph
, E
);
}
}
for (V
=0; V
<Graph
->Nv
; V
++)
scanf(" %c", &(Graph
->G
[V
].Data
));
return Graph
;
}
图的遍历
DFS
BFS
ListComponent
最短路径
常用术语
最短路径、源点、终点
最短路径分类
单源最短路径
无权图
网络
上述代码中寻找未收录定点中dist最小者
多源最短路径
单源最短路径调用V遍(适用于稀疏图)Floyd算法(稠密图)
Floyd算法
最小生成树
贪心算法
Prim算法
伪代码描述
Kruskal算法
拓扑排序
AOV
事件在结点上,有向边代表某种约束关系验证某件事情能否完成
AOE
在拓扑序的基础之上得出关键路径缩短整个工期的事件(当有多条关键路径时,缩短整体工期不能只改变一条关键路径)