第7章 图

7.2.2 图的存储结构

1.多重链表
2.图的邻接矩阵存储结构定义

#define MaxSize 100
typedef struct{
    char V[100];//顶点表
    int Edge[100][100];//边表
    int vexnum,arcnum;//图的当前顶点数和弧数
}MGraph;

3.图的邻接表存储结构定义

typedef struct ArcNode{
    int data;
    struct ArcNode *next;
}ArcNode;
typedef struct VNode{
    int data;
    ArcNode *first;
}VNode,AdjList[100];
typedef struct{
    AdjList vertices;
    int vexnum,arcnum;
}ALGraph;

4.紧缩邻接表

图的基本操作

Adjacent(G,x,y):判断图G是否存在边<x,y>或(x,y).
Neighbors(G,x):列出图G中与结点x邻接的边。
InsertVertex(G,x):在图G中插入顶点x。
DeleteVertex(G,x):从图G中删除顶点x.
AddEdge(G,x,y):如果无向边(x,y)或有向边<x,y>不存在,则向图G中添加该边。
RemoveEdge(Gx,y):如果无向边(x,y)或有向边<x,y>存在,则从图G中删除该边。
FirstNeighbor(G,x):求图G中顶点x的第一个邻接点,若有则返回顶点号。 若x没有邻接或图中不存在x,则返回-1。
NextNeighbor(G,x,y):假设图G中顶点y是顶点x的一个邻接点,返回除y之外顶点x的一个邻接点的顶点号,若y是x的最后一个邻接点,则返回-1。
Get_edge_value(G,x,y):获取图G中边(x,y)或<x,y>对应的权值。
Set_edge_value(G,x,y,v):设置图G中边(x,y)或<x,y>对应的权值为v。

7.2.3 图的遍历

1.广度优先搜索BFS

bool visited[G.vexnum];
void BFSTraverse(Graph G)
{
    for(int i=0;i<G.vexnum;i++)
        visited[i]=false;
    InitQueue(Q);
    for(int i=0;i<G.vexnum;i++)
    {
        if(!visited[i])
            BFS(G,i)
    }
}
void BFS(Graph G,int v)
{
    visit[v];
    visited[v]=true;
    EnQueue(Q,v);
    while(!IsEmpty(Q))
    {
        DeQueue(Q,v);
        for(w=FirstNeighbor(Q,v);w>=0;w=NextNeighbor(Q,w))
        {
            if(!visited[w])
            {
                visit[w];
                visited[w]=true;
                EnQueue[Q,w];
            }
        }
    }
}

BFS算法求解单源最短路径问题

void BFS MIN Distance(Graph G,int u){
	//d[i]表示从u到i结点的最短路径
	for(i=0;i<G.vexnum;++i)
		d[i]=;//初始化路径长度
	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
}

2.深度优先搜索DFS

bool visited[MAX_VERTEX_NUM];//访问标记数组
void DFSTraverse(Graph G)
{
    //对图G进行深度优先遍历,访问函数为visit()
    for(v=0;v<G.vexnum;++v)
        visited[v]=FALSE;
    for(v=0;v<G.vexnum;++v)
        if(!visited[v])
            DFS(G,v);
}
void DFS(Graph G,int v){
    visit(v);
    visited[v]=TRUE;
    for(w=FirstNeighbor(G,v);w=NextNeighor(G,v,w))
        if(!visited[w]){
            DFS(G,w);
        }
}

最小生成树算法

通用的最小生成树算法

GENERIC_MST(G){
	T=NULL;
	while T未形成一棵生成树;
		do 找到一条最小代价边(u,v)并且加入T后不会产生回路;
			T=T∪(u,v);
}

普利姆Prim算法

void Prim(G,T){
	T=;//初始化空树
	U={w};//添加任一顶点w
	while((V-U)!=){//若树中不含全部顶点(u,v)是使ueU与ve(V-U),且权值最小的边;
		T=T∪{(u,v)};//边归入树
		U=U∪{v};//顶点归入树
}

克鲁斯卡尔算法Kruskal

void Kruskal(V,T){
	T=V;//初始化树T,仅含顶点
	nums=n;//连通分量数
	while(numS>1){//如果连通分量数大于1
		从E中取出权值最小的边(v,u);
		if(v和u属于T中不同的连通分量){
			T=T∪{(v,u)
		};//将此边加入生成树中
		nums--;//连通分量数减1
	}
}

7.2.4 最短路径

Dijkstra算法求最短路径问题
在这里插入图片描述
Floyd算法求各顶点之间最短路径问题
在这里插入图片描述
在这里插入图片描述

拓扑排序

①从DAG图中选择一个没有前驱的顶点并输出;

②从图中删除该顶点和所有以它为起点的有向边;

③重复①和②直到当前的DAG图为空或者当前图中不存在无前驱的顶点为止。而后一种情况则说明有向图中必然存在环;

bool TopologicalSort(Graph G){
	InitStack(S);//通过栈S保存所有入度为0的顶点以便访问
    for(int i=0;i<G.vexnum;i++)//找出入度为0的顶点的过程
        if(indegree[i]==0)//indegree数组保存了当前所有顶点的入度
            Push(S,i);
    int count=0;//记录当前访问顶点的个数
    while(!isEmpty(S)){//循环2、3,如果为空,则不存在入度为0的顶点了 
        Pop(S,i);//弹出入度为0的顶点
        print[count++]=i;//用来保存拓扑排序的序列 
        for(p=G.Vertices[i].firstarc;p;p=p->nextarc){
        //遍历边表的过程,将p初始化了对应顶点的头指针,然后判断该指针是否为空
            v=p->adjvex;//用辅助变量v保存当前边表的内容,也就是该边的另一个端点 
            if(!(--indegree[v]))//减小了另一个端点的入度,然后如果该顶点的入度为0的话就对其进行压栈操 作,将其保存到栈中
                push(S,V);    
        }  
    }    
    if(count<G.vexnum)//如果访问的顶点个数小于该图中的顶点个数,则表示有些顶点没有访问,就返回false,表示拓扑排序失败,
    //如果访问了所有的顶点则放回true,表示访问了所有的顶点 
        return false;
    else  
        return true; 
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值