图的存储
邻矩阵法
#define MAXVertexNum 100//顶点数目最大值
typedef char VerteType;//顶点的数据类型
typedef int EdgeType;//带全图中边上权值的数据类型
typedef struct{
VerteType Vex[MAXVertexNum];顶点表
EdgeType Edge[MaxVertexNumm][MAXVertexNum];//邻接矩阵,边表
int vexnum,arcnum;//当前顶点数和边数
}MGraph
邻接表法
#define MAXVertexNum 100//顶点数目最大值
typedef truct ArcNode{
//边表结点
int adjvex; //该弧所指向的顶点为位置
truct ArcNode *next; //指向下一条弧的指针
InfoType info; //网的边权
}ArcNode;
typedef struct VNode{
//顶点表结点
VertexType data;//顶点信息
ArcNode *first;//指向第一天已覆盖点的弧指针
}
typedef struct{
AdjList vertices;//邻接表
int vexnum,arcnum;/顶点数和弧数
}ALGraph//以邻接表存储的图类型
十字链表
弧结点
tailvex | headvex | hlink | tlink | info |
---|
顶点结点
data | fist | firstout |
---|
多重邻接表
每条边用一个结点表示的结构
mark | ivex | ilink | ivex | jlink | info |
---|
ilink/jlink指向下一条依附于顶点ivex/jvex的边;
ivex/jvex为该边依附的两个顶点
mark标记是否被搜索过
info指向河边相关的各种信息指针域
图的基本操作
判断图G是否存在边<x,y>或(x,y)。
Adjacent(G,<x,y>)
列出图G中与x邻接的边。
Neighbors(G,x)
图G中插入顶点x。
InsertVertex(G,x)
删除顶点x。
DeleteVertex(G,x)
若边(x,y)不存在,则添加该边。
AddEdge(G,x,y)
若边(x,y)存在,则删除该边。
RemoveEdge(G,x,y)
求图G中顶点x的第一个邻接点,有则返回顶点号。不存在返回-1。
FirstNeighbor(G,x)
假设图G中顶点y是顶点x的一个邻接点,返回除y外顶点x的下一临界点的顶点号,若y是x最后一个邻接点,返回-1。
NextNeighbor(G,x,y)
获得图G中边(x,y)的权。
Get_edge_value(G,x,y)
设置图G中边(x,y)的权为v。
Set_edge_value(S,x,y,v)
图的遍历
广度优先-队列(BFS)
bool visited[MAX_VERTEX_NUM];//访问标记数组
void BFSTraverse(Graph G){
//对图G进行BFS
for(i=0;i<G.vexnum;i++)
visited[i]=FALSE; //访问标记数组初始化
Initqueue(Q); //辅助队列初始化
for(i=0;i<G.vexnum;i++) //0号开始遍历
if(!visited[i]) //对每个连通分量调用一次BFS
BFS(G,i);
}
void BFS(Graph G,int v){
visit(v); //访问初始顶点
visited[v]=TRUE; //标记已访问点
Enqueue(Q,v); //顶点v入队Q
while(!isEmpty(Q)){
DeQueue(Q,v); //v出队Q
for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))//检查v的邻接点
if(!visitex[w]){
//w为v未访问邻结点
visit(w);
visited[w]=TRUE;
EneQueue(Q,w);
}//if
}//while
}
求单元最短路
void BFS_MIN_Distance(Graph G,int u){
//d[i]表示从u到i结点的最短路
for(i=0;i<G.vexnum;i++)
d[i]=9999; //初始化路径长度
visited[u]=TRUE;d[u]=0;
EnQueue(Q,u);
while(!isEmpty(Q)){
//BFS主过程
DeQueue(Q,u); //队头元素u入队
for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u,w))
if(!visited[w]){
//w为u的尚未访问的邻接顶点
visited[w]=TRUE; //设置已访问标记
d[w]=d[u]+1; //路径长度加1
Enqueue(Q,w); //顶点w入队
}//if
}//while
}
深度优先-栈(DFS)
bool visited[MAX_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G){
//对G进行深度优先遍历
for(v=0;v<G.vexnum;++v)
visited[v]=FALSE; //初始化标记数组已访问情况
for(v=0;v<G.vexnum;v++)//从v=0开始遍历
if(!visited[v])
DFS(G,v);
}
void DFS(Graph G,int v){
visited(v);//访问v
visited[v]=TRUE;//标记已访问点
for(w=FirstBeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
if(!visited[w]){
DFS(G,w);
}//if
}
图的应用
最小生成树(MST)
prim
cruskal
最短路径
dijkstra
Floyd
拓扑排序
v./n.