c语言之图的定义及遍历

图的两种存储方式

一、邻接矩阵:

邻接矩阵的结构定义

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;

}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/chinabhlt/article/details/8858312
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞