c语言之图的定义及遍历
来源:互联网 发布:jenkins php docker 编辑:程序博客网 时间:2024/06/05 00:52
图的两种存储方式
一、邻接矩阵:
邻接矩阵的结构定义
typedef struct
{
int no; //顶点编号
char info; //存储顶点的其他信息
}VertexType;
typedef struct //图的定义
{
int edges[maxsize][maxsize]; //定义二维数组存储边的关系
int n,e; //存储顶点数和边数
VertexType vex[maxsize]; //存储节点信息
}MGraph;
二、邻接表的结构定义
typedef struct AcNode
{
int adjvex;
struct AcNode *nextarc;
}AcNode; //定义链表的节点
typedef struct VNode
{
int data;
struct VNode *firstAcNode;
}VNode; //定义顶点
typedef struct
{
VNode adjlist[maxsize];
int n,e;
}AGraph;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
图的深度优先遍历
(以邻接表为存储结构)
int visit[maxsize]; //存储节点访问信息,初始化为0。因图中可能存在环路,当前节点将来可能再次经过,因此要对每个顶点进行标记,以免重复访问
void DFS(AGraph *G, int v)
{
AcNode *p;
visit[v] = 1;
Visit(v); //Visit函数代表一类访问顶点v操作
p = G->adjlist[v].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0) //若为被访问,则递归访问
DFS(G,p->adjvex);
p = p->nextarc;
}
}
图的广度优先遍历(需要借助队列实现)
(以邻接表为存储结构)
void BFS(AGraph G, int v, int visit[maxsize])
{
AcNode *p;
int que[maxsize],front = 0,rear = 0;
int j;
Visit(v); //Visit函数代表一类访问顶点v操作
visit[v] = 1;
rear = (rear+1)%maxsize; //当前节点进队
que[rear] = v;
while(front != rear)
{
front = (front+1)%maxsize; //顶点出队
j = que[front];
p = G->adjlist[j].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0)
{
Visit(p->adjvex);
visit[p->adjvex] = 1;
rear = (rear+1)%maxsize; //该顶点进队
que[rear] = p->adjvex;
}
p = p->nextarc;
}
}
}
例题1:
设计算法,求不带权无向连通图图G中距离顶点v最远的一个顶点(最远是指到达v路径长度最长)
分析:图的广度优先搜索遍历方式体现由图中某个顶点开始,以由近向远层层扩展的方式遍历图中节点的过程。及最后遍历节点即为最远节点
int BFS(AGraph *G, int v)
{
AcNode *p;
int que[maxsize],front = 0,rear = 0;
int j;
int visit[maxsize] = 0; //初始化为0
visit[v] = 1;
rear = (rear+1)%maxsize; //当前节点进队
que[rear] = v;
while(front != rear)
{
front = (front+1)%maxsize; //顶点出队
j = que[front];
p = G->adjlist[j].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0)
{
visit[p->adjvex] = 1;
rear = (rear+1)%maxsize; //该顶点进队
que[rear] = p->adjvex;
}
p = p->nextarc;
}
}
return j;
}
例题2:
设计算法,判断无向图G是否是一棵树。若是返回1,否则返回0
分析:一个无向图是一棵树的条件是有n-1 条边的连通图,n为图中顶点个数。边和顶点的数目是否满足条件可由图的信息直接判断,连通与否可以用遍历能否访问到所有顶点来判断。
void DFS(AGraph *G, int v, int &vn, int &en)
{
AcNode *p;
visit[v] = 1;
++vn;
p = G->adjlist[v].firstAcNode;
while(p != NULL)
{
++en;
if(visit[p->adjvex] == 0)
DFS(G,p->adjvex,vn,en);
p = p->nextarc;
}
}
int GisTree(AGraph *G)
{
int vn = 0, en = 0;
int i;
for(i = 1; i <= G->n; ++i)
visit[i] = 0;
DFS(G, 1, vn, en);
if(vn == G->n && (G->n-1) == en/2)
//如果遍历过程中访问过的顶点和图中顶点数相等,且边数等于顶点数减1,即证明是树
return 1;
else
return 0;
}
一、邻接矩阵:
邻接矩阵的结构定义
typedef struct
{
int no; //顶点编号
char info; //存储顶点的其他信息
}VertexType;
typedef struct //图的定义
{
int edges[maxsize][maxsize]; //定义二维数组存储边的关系
int n,e; //存储顶点数和边数
VertexType vex[maxsize]; //存储节点信息
}MGraph;
二、邻接表的结构定义
typedef struct AcNode
{
int adjvex;
struct AcNode *nextarc;
}AcNode; //定义链表的节点
typedef struct VNode
{
int data;
struct VNode *firstAcNode;
}VNode; //定义顶点
typedef struct
{
VNode adjlist[maxsize];
int n,e;
}AGraph;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
图的深度优先遍历
(以邻接表为存储结构)
int visit[maxsize]; //存储节点访问信息,初始化为0。因图中可能存在环路,当前节点将来可能再次经过,因此要对每个顶点进行标记,以免重复访问
void DFS(AGraph *G, int v)
{
AcNode *p;
visit[v] = 1;
Visit(v); //Visit函数代表一类访问顶点v操作
p = G->adjlist[v].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0) //若为被访问,则递归访问
DFS(G,p->adjvex);
p = p->nextarc;
}
}
图的广度优先遍历(需要借助队列实现)
(以邻接表为存储结构)
void BFS(AGraph G, int v, int visit[maxsize])
{
AcNode *p;
int que[maxsize],front = 0,rear = 0;
int j;
Visit(v); //Visit函数代表一类访问顶点v操作
visit[v] = 1;
rear = (rear+1)%maxsize; //当前节点进队
que[rear] = v;
while(front != rear)
{
front = (front+1)%maxsize; //顶点出队
j = que[front];
p = G->adjlist[j].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0)
{
Visit(p->adjvex);
visit[p->adjvex] = 1;
rear = (rear+1)%maxsize; //该顶点进队
que[rear] = p->adjvex;
}
p = p->nextarc;
}
}
}
例题1:
设计算法,求不带权无向连通图图G中距离顶点v最远的一个顶点(最远是指到达v路径长度最长)
分析:图的广度优先搜索遍历方式体现由图中某个顶点开始,以由近向远层层扩展的方式遍历图中节点的过程。及最后遍历节点即为最远节点
int BFS(AGraph *G, int v)
{
AcNode *p;
int que[maxsize],front = 0,rear = 0;
int j;
int visit[maxsize] = 0; //初始化为0
visit[v] = 1;
rear = (rear+1)%maxsize; //当前节点进队
que[rear] = v;
while(front != rear)
{
front = (front+1)%maxsize; //顶点出队
j = que[front];
p = G->adjlist[j].firstAcNode;
while(p != NULL)
{
if(visit[p->adjvex] == 0)
{
visit[p->adjvex] = 1;
rear = (rear+1)%maxsize; //该顶点进队
que[rear] = p->adjvex;
}
p = p->nextarc;
}
}
return j;
}
例题2:
设计算法,判断无向图G是否是一棵树。若是返回1,否则返回0
分析:一个无向图是一棵树的条件是有n-1 条边的连通图,n为图中顶点个数。边和顶点的数目是否满足条件可由图的信息直接判断,连通与否可以用遍历能否访问到所有顶点来判断。
void DFS(AGraph *G, int v, int &vn, int &en)
{
AcNode *p;
visit[v] = 1;
++vn;
p = G->adjlist[v].firstAcNode;
while(p != NULL)
{
++en;
if(visit[p->adjvex] == 0)
DFS(G,p->adjvex,vn,en);
p = p->nextarc;
}
}
int GisTree(AGraph *G)
{
int vn = 0, en = 0;
int i;
for(i = 1; i <= G->n; ++i)
visit[i] = 0;
DFS(G, 1, vn, en);
if(vn == G->n && (G->n-1) == en/2)
//如果遍历过程中访问过的顶点和图中顶点数相等,且边数等于顶点数减1,即证明是树
return 1;
else
return 0;
}
- c语言之图的定义及遍历
- C语言数据结构之图的遍历
- C语言宏的定义及使用
- 图的结构定义及遍历方法
- C语言基本数据结构之三(图的广度及深度遍历,求单源最短路径的Dijkstra算法)
- C语言实现图的邻接矩阵存储结构及深度优先遍历和广度优先遍历
- 黑马程序员--C语言之for语句的定义及实现
- AVL树的插入、删除及遍历C语言实现
- 【C语言】C语言之枚举定义和宏定义的技巧1
- C语言之宏定义
- C语言之宏定义
- c语言之宏定义
- C语言 函数同名宏的定义及注意事项
- 十字链表的定义及C语言描述
- C语言宏定义中的#,##,#@及\符号的作用
- c语言宏定义中的#,##,#@及\符号的作用
- C语言宏定义中的#,##,#@及\符号的作用
- C语言数据结构----栈的定义及实现
- mysql event例子
- This Android SDK requires Android Developer Toolkit version&n
- Linux中常用的批量操作文件命令
- setsockopt 设置socket 详细用法
- No unexpired provisioning profiles found that contain any of the keychain's signing certificates
- c语言之图的定义及遍历
- 如果你也是名“懒”站长
- skysql
- @Override must override a superclass method 问题解决
- mysql动态创建表分区
- 网络贷款平台有待改善为公开化透明化
- 安卓开发 访问网络 4.2系统下调用getResponseCode 抛异常
- c# 使用委托操作线程
- DataGridView导入Excel时,出现了“未将对象引用设置到对象的实例”的解决办法