#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 40
typedef int DataType;
int visited[MAXNUM]={0};//访问节点标识
int vexInNum[MAXNUM]={0};//统计节点的入度
//无向图 测试数据 8 0 1 0 2 0 3 1 2 1 4 2 5 3 1 3 6 4 0 4 1 4 6 6 4 6 7 7 6 -1 -1
//有向图 测试数据 需是无环图 做拓扑排序 5 2 0 2 1 0 1 0 4 1 3 4 3 -1 -1
/*图的邻接矩阵结构*/
typedef struct
{
int vexnum;//顶点个数
int arcs[MAXNUM][MAXNUM];//邻接矩阵
}MGraph,*PMGraph;
/*队列的定义用于广度优先遍历*/
typedef struct{
int front;//头指针
int rear;//尾指针
int count;//计数器
DataType data[MAXNUM];
}CirQueue,*PCirQueue;
//初始化
void initQueue(PCirQueue q)
{
q->front=q->rear=0;
q->count=0;
}
//判定队空
int emptyQueue(PCirQueue q)
{
return q->count==0;
}
//判定队满
int fullQueue(PCirQueue q)
{
return q->count==MAXNUM;
}
//入队
void entryQueue(PCirQueue q,DataType x)
{
if(fullQueue(q))
{
printf("队列已满\n");
exit(1);
}
q->count++;
q->data[q->rear]=x;
q->rear=(q->rear+1)%MAXNUM;
}
//出队 返回出来的元素
DataType deleteQueue(PCirQueue q)
{
DataType temp;
if(emptyQueue(q))
{
printf("队已经为空\n");
exit(1);
}
q->count--;
temp=q->data[q->front];
q->front=(q->front+1)%MAXNUM;
return temp;
}
/*图的初始化*/
void initGraph(PMGraph g)
{
int i,j,k;
printf("输入顶点个数:\n");//校验输入的顶点个数
scanf("%d",&k);
g->vexnum=k;
//初始化边信息
for(i=0;i<k;i++)
for(j=0;j<k;j++)g->arcs[i][j]=0;
printf("输入边信息:\n");
while(1)
{
scanf("%d%d",&i,&j);
if(i==-1&&j==-1)break;
g->arcs[i][j]=1;
}
}
/*图的邻接矩阵*/
void outPutGraph(PMGraph g)
{
int i,j,k;
k=g->vexnum;
for(i=0;i<k;i++)
{
for(j=0;j<k;j++)
{
printf("%-3d",g->arcs[i][j]);
}
printf("\n");
}
}
/*拓扑排序---参考深度优先遍历思路*/
void topSort(PMGraph g,int i)
{
int j;
printf("V%d ",i);
visited[i]=1;
//去掉i 到j的入度
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[i][j]==1)
{
vexInNum[j]-=1;
}
if(vexInNum[j]==0&&visited[j]==0)topSort(g,j);
}
}
void topTraver(PMGraph g)
{
int i,j;
//初始化入度点数
for(i=0;i<g->vexnum;i++)
{
vexInNum[i]=0; visited[i]=0;
}
//统计图g的各个节点的入度 数组下标标示节点 数组值表示入度数
for(i=0;i<g->vexnum;i++)
{
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[j][i]==1)vexInNum[i]+=1;
}
}
for(i=0;i<g->vexnum;i++){
if(vexInNum[i]==0&&visited[i]==0)
{
topSort(g,i);
}
}
}
/*深度优先搜索DFS*/
void DFS(PMGraph g,int i)
{
int j;
//打印表示已访问
printf("V%d ",i);
visited[i]=1;
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[i][j]==1&&!visited[j])DFS(g,j);
}
}
void DFSTraver(PMGraph g)
{
int i;
//初始化访问节点
for(i=0;i<g->vexnum;i++)visited[i]=0;
for(i=0;i<g->vexnum;i++)
{
if(!visited[i])
{
DFS(g,i);
}
}
}
/*广度优先搜索BFS 使用队列遍历*/
void BFS(PMGraph g,int i)
{
CirQueue q;
int j;
printf("V%d ",i);
visited[i]=1;
initQueue(&q);//初始化队列
entryQueue(&q,i);
while(!emptyQueue(&q))
{
int v=deleteQueue(&q);
for(j=0;j<g->vexnum;j++)
{
if(g->arcs[v][j]==1&&visited[j]==0)
{
printf("V%d ",j);
visited[j]=1;
entryQueue(&q,j);
}
}
}
}
void BFSTraver(PMGraph g)
{
int i;
//初始化访问节点
for(i=0;i<g->vexnum;i++)visited[i]=0;
for(i=0;i<g->vexnum;i++)
{
if(!visited[i])
{
BFS(g,i);
}
}
}
/*最小生成树*/
void main()
{
MGraph *g = (PMGraph)malloc(sizeof(MGraph));
initGraph(g);
printf("图的邻接矩阵:\n");
outPutGraph(g);
printf("图的深度优先遍历:\n");
DFSTraver(g);
printf("\n图的拓扑排序:\n");
topTraver(g);
printf("\n图的广度优先遍历:\n");
BFSTraver(g);
}
分享到:
相关推荐
数据结构中有向图和无向图的c语言实现.pdf
无向图 有向图 有向网 无向网 深度优先遍历 C语言 用户操纵界面
总之,这个项目涵盖了无向图的邻接表存储、深度优先搜索以及先序遍历等核心概念,是学习和实践图论及C语言编程的好例子。通过这个项目,开发者可以深入了解图的存储和遍历算法,并提升解决复杂问题的能力。
无向图中,所有顶点的度数之和等于边数的两倍,因为每条边贡献了两个度。 在图的存储结构中,邻接矩阵是最直观的方法。对于一个具有n个顶点的图,邻接矩阵是一个n×n的矩阵,矩阵中的每个元素表示对应顶点之间是否...
对于无向图而言,度数是指所有与之相连的顶点数量;而对于有向图,则分为入度(指向该顶点的边的数量)和出度(从该顶点出发的边的数量)。 5. **打印图** (`PrintGraph`) ```c Status PrintGraph(MGraph G); `...
由于拓扑排序只适用于无环图,因此我们可以利用这个特性来检测有向图中是否存在回路。 以下是实现这个功能的一种常见方法,使用深度优先搜索(DFS)或广度优先搜索(BFS): 1. **深度优先搜索(DFS)**:从任意未...
无向图的课设,有程序和报告,内容有邻接矩阵建立无向图、邻接矩阵遍历、广度优先搜索遍历、深度优先搜索遍历、(最小生成树普里姆(Prim)算法)、单源最短路径(地杰斯特拉(Dijkstra)算法),程序打开即可运行。
"C语言寻找无向图两点间的最短路径" 本资源主要介绍了使用C语言寻找无向图两点间的最短路径,通过邻接表实现无向图,并使用广度优先遍历找到两点之间的最短路径。下面是相关的知识点: 1. 无向图:无向图是一种图...
### C语言实现无向图的深度优先遍历 #### 概述 本篇文章将通过一个具体的C语言程序实例,详细解析如何实现无向图的深度优先遍历算法。该算法适用于计算机科学中的图形处理领域,尤其在解决路径寻找、网络分析等...
带权无向图在现实世界中有广泛的应用,例如在网络设计中确定最低成本的线路配置,在地理信息系统中计算两点间的最短路径,在社交网络分析中衡量不同个体之间的紧密程度,以及在机器学习中构建图模型等。 ### 结论 ...
完全无向图是所有不同顶点间都有一条边的无向图,而完全有向图则要求所有不同顶点间都有一对方向相反的弧。 图的应用非常广泛,如在路由算法、社交网络分析、电路设计、物流路径规划等领域都有其身影。图的权值可以...
这个实验有助于理解无向图的内部工作原理,同时加深对C语言编程的理解。通过实际操作,学生可以更好地掌握数据结构和算法,提高问题解决能力。在实际的项目开发中,这样的基础将为处理复杂的问题提供坚实的基础。
图的创建,以及利用图的几种不同的存储方法而实现的不同的创建方法,对无向图,有向图,无向网,以及有向网都与很好的说明,是你学习数据结构时必不可少的好东西.,,,,
在这个场景中,我们有n个城市,每个城市代表一个顶点,而城市之间的交通线路则由边来表示,每条边的权重表示建设这条线路的造价。我们的目标是找到一个连接所有城市的最小成本的边集。 在C语言中实现最小生成树算法...
通过上述C语言实现,我们可以对任何有向无环图进行拓扑排序。这个过程涉及到图的遍历、队列的操作以及邻接表的管理,是数据结构和算法学习中的经典问题。掌握这种方法不仅可以加深对图的理解,也有助于提升编程解决...
根据边的方向,图可以分为无向图(边没有方向)和有向图(边有方向)。此外,图还可以是加权图(边附带数值,表示两个顶点间的关系强度)或无权图(边不携带任何附加信息)。 **二、邻接矩阵** 在C语言中,我们通常...
无向图的边没有方向,也就是说,如果节点A与节点B之间有一条边,那么节点B与节点A也有一条边。在无向图中,度(degree)指的是一个节点与其他节点相连的边的数量。无向图在社交网络、交通网络等领域有着广泛的应用。...
### 无向图的邻接矩阵存储及输出详解 在计算机科学中,图是一种重要的数据结构,用于表示对象之间的关系。图由顶点(或节点)和边组成,其中边可以是有向的或无向的。本文将详细介绍无向图的邻接矩阵存储方式以及...
无向图与有向图 - 无向图:图中的边没有方向性,即边是双向的。 - 有向图:图中的边具有方向性,表示了顶点间的关系方向。 #### 3. 连通性 - 连通无向图:任意两个顶点之间都存在路径的无向图。 - 连通有向图:...
- 图可以分为有向图(Directed Graph)和无向图(Undirected Graph)。有向图的边具有方向,而无向图的边没有方向。 2. **深度优先搜索(DFS, Depth-First Search)** - 深度优先搜索是一种用于遍历或搜索树或图的...