数据结构--图

                                         **图**

新的一周,最近感觉时间过得好快啊!!!
争取在开学前整理完!!!开学后二刷王道!!!
(加油!!!!!)
直接上图吧!
在这里插入图片描述
开始正题!!
1.图的存储

//图的邻接矩阵
#define MaxVertexNum 100 //顶点数目的最大值
typedef char VertexType;//顶点的数据类型
typedef int EdgeType;//带权图中边上权值的数据类型
typedef struct{
	VertexType Vex[MaxVertexNum];//顶点表
	EdgeType Edge[MaxVerteNum][MaxVerteNum];//邻接矩阵,边表
	int vexnum,arcnum;//图的当前顶点数和边数 
}MGraph; 
//图的邻接表存储
#define MaxVertexNum 100 //图中顶点数目的最大值
typedef struct ArcNode{  //边表结点
   int adjvex;//该边所指向的顶点的位置 
   struct ArcNode *next; //指向下一条边的指针 	
}ArcNode;
typedef struct VNode{ //顶点表结点
   VertexType data;//顶点信息
   ArcNode *first;//指向第一依附该顶点的边的指针 
}VNode,AdjList[MaxVertexNum];
typedef struct{
	AdjList vertices;//邻接表
	int vexnum,arcnum;//图的顶点数和边数 
}ALGraph; //ALGraph是以邻接表存储的图类型

2.十字链表的结构定义

//图的十字链表结构定义
#define MaxVertexNum 100
typedef struct ArcNode{ //边表结点
   int tailvex,headvex;//该边的头尾结点
   struct ArcNode *hlink,*tlink;//分别指向边头相同和边尾相同的结点 
}ArcNode; 
typedef struct VNode{//顶点表结点
    VertexType data;//顶点信息
	ArcNode *firstin,*firstout;//珍惜第一条入边和出边 	
}VNode;
typedef struct{
	VNode xlist[MaxVertexNum];//邻接表
	int vexnum,arcnum;//图的顶点数和边数 
}GLGraph;//GLGraph是以十字邻接存储的图类型

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

//图的邻接多重表存储结构定义
#define MaxVertexNum 100
typedef struct ArcNode{//边表结点
 bool mark;//访问标记
 int ivex,jvex;//分别指向该边的两个结点
 struct ArcNode *ilink,*jlink;//分别指向两个顶点的下一条边 	
}ArcNode; 
typedef struct VNode{ //顶点表结点
   VertexType data;//顶点信息
   ArcNode *firstedge;//指向第一条依附该顶点的边 
}VNode;
typedef struct{
	VNode adjmulist[MaxVertexNum];//邻接表
	int vexnum,arcnum;//图的顶点数和边数 
}AMLGraph;//AMLGraph是以邻接多重表存储的图类型

4.广度优先算法的伪代码

//广度优先搜索算法的伪代码
bool visited[MAX_VERTEX_NUM];//访问标记数组
void BFSTraverse(Graph G){
	//对图G进行广度优先遍历,设访问函数为visit()
	for(int i=0;i<G.vexnum;i++)
	  visited[i]=FALSE;//访问标记数组初始化
	  InitQueue(Q);//初始化辅助队列Q
	  for(i=0;i<G.vexnum;i++) //从0号顶点开始遍历
	    if(!visited[i])//对每个连通分量调用一次BFS
		  BFS(G,i);//vi未被访问过,从vi开始BFS 
} 
void BFS(Graph G,int v){
	//从顶点v出发,广度优先遍历图G,算法借助一个辅助队列Q
	visit(v);//访问初始顶点v
	visited[v]=TRUE;//对v做已访问标记
	Enqueue(Q,v);//顶点v入队列
	while(!isEmpty(Q)) {
		Dequeue(Q,v);//顶点v出队列
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)) //检测v所有邻接点
		//FirstNeighbor(G,v)求图G中顶点v的第一个邻接点,若有则返回顶点号。若u没有邻接点或图中不存在v,则返回-1 
		   if(!visited[w]) {
		   	//w为v的尚未访问的邻接顶点
			   visited[w]=TRUE;//对w做已访问标记
			   EnQueue(Q,w);//顶点w入队列 
		   }
	}
} 

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

//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))
		   //FirstNeighbor(G,u)求图G中顶点u的第一个邻接点,若有则返回顶点号。若u没有邻接点或图中不存在u,则返回-1 
		   //NextNeighbor(G,u,w)假设图G中顶点w是顶点u的一个邻接点,返回除w之外顶点u的下一个邻接点的顶点号,
		   //若w是u的最后一个邻接点,则返回-1 
		      if(!visited[w]){
		      	//w为u的尚未访问的邻接顶点
				  visited[w]=TRUE;//设已访问标记
				  d[w]=d[u]+1;//路径长度+1
				  EnQueue(Q,w);//顶点w入队 
			  } 
	   }
 } 

5.递归形式 深度优先算法

//递归形式 深度优先算法
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)
{
	//从顶点v出发,采用递归思想,深度优先遍历图G
	visit(v);//访问顶点v
	visited[v]=TRUE;//设已访问标记
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v.w))
	   if(!visited[w]){ //w为u的尚未访问的邻接顶点 
	   	DFS(G,w);
	   } 
}

6.弗洛伊德算法(天勤)

//弗洛伊德算法(天勤)
void Floyd(MGraph g,int Path[][maxSize]) 
{
	int i,j,k;
	int A[maxSize][maxSize];
	//双循环对数组A[][]和Path[][]进行了初始化
	for(i=0;i<g.n;i++)
	{
		A[i][j]=g.edges[i][j];
		Path[i][j]=-1;
	 } 
	//下面三层循环是本算法主要操作,完成了以k为空间点对所有的顶点对{i,j}进行行检测和修改
	for(k=0;k<g.n;++k)
	  for(j=0;j<g.n;++j)
	    if(A[i][j]>A[i][k]+A[k][j]) 
	    {
	    	A[i][j]>A[i][k]+A[k][j];
	    	Path[i][j]=k;
		}
}

7.拓扑排序

//拓扑排序
bool TopologicalSort(Graph G)
{
	//若G存在拓扑序列,返回true,否则返回false,这时G中存在环
	InitStack(S);//初始化栈,存储入度为0的顶点
	for(int i=0;i<G.vexnum;i++)
	   if(indegree[i]==0)
	      Push(S,i);//将所有入度为0的顶点进栈
		 int count=0;//计数,记录当前已经输出的顶点数
		 while(!IsEmpty(S)) {
		 	///栈不空,则存在入度为0的顶点
			 Pop(S,i);//栈顶元素出栈
			 print[count++]=i;//输出顶点i
			 for(p=G.vertices[i].firstarc;p->nextarc){
			 	//将所有i指向的顶点的入度减一,并且将入度减为0的顶点压入栈S
				v=p->adjvex;
				if(!(--indegree[v])) 
				  Push(S,v);//入度为0,则入栈 
			 } 
		 }
		 if(count<G.vexnum)
		   return false;//排序失败,有向图中有回路
		 else
		   return true;//拓扑排序成功 
 } 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值