【考研05】图的遍历

1. 深度优先遍历

int visit[maxSize];
/*v是起点编号,visit[]是一个全局数组,作为顶点的访问标记,初始时所有元素均为0
表示所有顶点都未被访问*/
void DFS(AGraph *G,int v)
{
	ArcNode *p; //边结点
	visit[v]=1; //置已访问标记
	Visit(v); 
	p = G->adjlist[v].firstarc;
	while(p != NULL)
	{
		if(visit[p->adjvex] == 0) //若顶点未访问,则递归访问它
			DFS(G,p->adjvex);
		p = p->nextarc; //p指向顶点v的下一条边的
	}
}

2. 广度优先搜索

void BFS(AGraph *G,int v,int visit[maxSize]) //visit[]数组被初始化全为0
{
	ArcNode *p; //边结点
	int que[maxSize],front=-1,rear=-1; 
	int j;
	Visit(v);
	visit[v] = 1;
	rear = (rear+1)%maxSize; //当前顶点v进队
	que[rear] = v;
	while(front != rear) //队空的时候说明遍历完成
	{
		front = (front+1)%maxSize; //顶点出队
		j = que[front];
		p = G->adjlist[j].firstarc; //p指向出队顶点j的第一条边
		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; //p指向j的下一条边
		}
	}
}

3. 拓扑排序

typedef struct
{
	char data;
	int count; //count用来统计顶点当前的入度
	ArcNode *firstarc;
}
int TopSort(AGraph *G)
{
	int i,j,n=0;
	int stack[maxSize],top=-1; //定义并初始化栈
	ArcNode *p; //边结点
	//这个循环将图中入度为0的顶点入栈
	for(i=0;i<G->n;++i)
		if(G->adjlist[i].count == 0)
		stack[++top] = i;
	while(top != -1)
	{
		i = stack[top--]; //顶点出栈
		++n; //计数器加1,统计当前顶点
		printf("%d",i); //输出当前顶点
		p = G->adjlist[i].firstarc;
		//这个循环实现了将所有由此顶点引出的边所指向的顶点的入度减1,
		//并将这个过程中入度为0的顶点入栈
		while(p != NULL)
		{
			j = p->adjvex;
			--(G->adjlist[j].count);
			if(G->adjlist[j].count == 0)
				stack[++top] = j;
			p = p->nextarc;
		}
	}
	if(n == G->n)
		return 1;
	else
		return 0;
}

4. 判断无向图G是否是一棵树

void DFS(AGraph *G,int v,int &vn,int &en)
{
	ArcNode *p;
	visit[v] = 1;
	++vn; //vn计数器自增1
	p = G->adjlist[v].firstarc;
	while(p != NULL)
	{
		++en; //边数自增1
		if(visit[p->adjvex] == 0)
			DFS(G,p->adjvex,vn,en);
		p = p->nextarc;
	}
}
int GisTree(AGraph *G)
{
	int vn=0,en=0,i;
	for(i=0;i<G->n;++i)
		visit[i] = 0;
	DFS(G,1,vn,en);
	//如果遍历过程中访问过的顶点数和图中的顶点数相等,
	//且边数等于顶点数减1,则证明是树
	if(vn == G->n && (G->n-1) == en/2)
		return 1;
	else
		return 0;
}

5. 求不带权无向连通图G中距离顶点v最远的一个顶点

int BFS(AGraph *G,int v)
{
	ArcNode *p; //边结点
	int que[maxSize],front=0,rear=0;
	int visit[maxSize];
	int i,j;
	for(i=0;i<G->n;i++)
		visit[i]=0;
	rear = (rear+1)%maxSize;
	que[rear] = v;
	visit[v] = 1;
	while(front != rear)
	{
		front = (front+1)%maxSize;
		j = que[front];
		p = G->adjlist[j].firstarc;
		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; //队空时,j保存了遍历过程中的最后一个顶点
}

6. 深度优先遍历非递归算法

void DFS(AGraph *g,int v)
{
	ArcNode *p;
	int stack[maxSize],top=-1; //定义一个栈来记录访问过程中的顶点
	int i,k;
	int visit[maxSize]; //顶点访问标记数组
	for(i=0;i<g->n;++i)
		visit[i] = 0;
	Visit(v); //访问该顶点
	visit[v] = 1; //标记起始顶点已被访问
	stack[++top] = v; //起始顶点入栈
	while(top != -1)
	{
		k = stack[top]; //取栈顶元素
		p = g->adjlist[k].firstarc; //p指向该顶点的第一条边
		//下面这个循环是p沿着边行走并将图中经过的顶点入栈的过程
		while(p != NULL && visit[p->adjvex]==1)
			p = p->nextarc; //找到当前顶点第一个没访问过的领接顶点或者p走到当前
							//链表尾部时,while循环停止
		if(p == NULL) //如果p到达当前链表尾部,则说明当前顶点的所有点都访问完毕
			--top;    //当前顶点出栈
		else
		{
			Visit(p->adjvex);
			visit[p->adjvex] = 1;
			stack[++top] = p->adjvex;
		}
	}
}

7. 图采用领接表存储,判别顶点i和顶点j(i!=j)之间是否有路径

int DFSTrave(AGraph *G,int i,int j)
{
	int k;
	for(k=0;k<G->n;++k)
		visit[k] = 0;
	DFS(G,i);  //可以换成BFS(G,i)
	if(visit[j] == 1)
		return 1;
	else
		return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本
好的,以下是C语言实现深度优先遍历的代码及注释: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 #define MAX_ARC_NUM 500 // 最大边数 typedef int VertexType; // 顶点的数据类型 typedef struct { VertexType vexs[MAX_VERTEX_NUM]; // 顶点数组 int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 邻接矩阵 int vexnum, arcnum; // 顶点数和边数 } MGraph; // 的邻接矩阵表示法 typedef struct { VertexType data; // 数据域 int firstarc; // 头结点 } VNode; typedef struct { VNode adjlist[MAX_VERTEX_NUM]; // 邻接表 int vexnum, arcnum; // 顶点数和边数 } ALGraph; // 的邻接表表示法 // 初始化邻接矩阵 void InitMGraph(MGraph *G) { int i, j; for (i = 0; i < MAX_VERTEX_NUM; i++) { for (j = 0; j < MAX_VERTEX_NUM; j++) { G->arcs[i][j] = 0; // 初始化为0 } } G->vexnum = 0; G->arcnum = 0; } // 添加顶点到邻接矩阵 void AddVertexToMGraph(MGraph *G, VertexType v) { G->vexs[G->vexnum++] = v; // 加入顶点数组 } // 添加边到邻接矩阵 void AddEdgeToMGraph(MGraph *G, int v1, int v2) { G->arcs[v1][v2] = 1; G->arcs[v2][v1] = 1; // 无向,所以要添加两条边 G->arcnum++; // 边数加1 } // 初始化邻接表 void InitALGraph(ALGraph *G) { int i; for (i = 0; i < MAX_VERTEX_NUM; i++) { G->adjlist[i].firstarc = -1; // 初始化为-1 } G->vexnum = 0; G->arcnum = 0; } // 添加顶点到邻接表 void AddVertexToALGraph(ALGraph *G, VertexType v) { G->adjlist[G->vexnum].data = v; // 加入数据 G->vexnum++; // 顶点数加1 } // 添加边到邻接表 void AddEdgeToALGraph(ALGraph *G, int v1, int v2) { ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = v2; // 邻接点为v2 p->nextarc = G->adjlist[v1].firstarc; // 头插法 G->adjlist[v1].firstarc = p; // 头节点指向新节点 G->arcnum++; // 边数加1 } // 深度优先遍历邻接矩阵 void DFSTraverseMGraph(MGraph G, int v, int visited[]) { printf("%d ", v); // 访问该顶点 visited[v] = 1; // 标记为已访问 int i; for (i = 0; i < G.vexnum; i++) { if (G.arcs[v][i] == 1 && !visited[i]) { // 如果存在边且未访问 DFSTraverseMGraph(G, i, visited); // 递归访问邻接点 } } } // 深度优先遍历邻接表 void DFS(ALGraph *G, int v, int visited[]) { printf("%d ", v); // 访问该顶点 visited[v] = 1; // 标记为已访问 ArcNode *p = G->adjlist[v].firstarc; while (p != NULL) { if (!visited[p->adjvex]) { // 如果邻接点未访问 DFS(G, p->adjvex, visited); // 递归访问邻接点 } p = p->nextarc; // 访问下一个邻接点 } } int main() { MGraph G; InitMGraph(&G); AddVertexToMGraph(&G, 1); AddVertexToMGraph(&G, 2); AddVertexToMGraph(&G, 3); AddVertexToMGraph(&G, 4); AddVertexToMGraph(&G, 5); AddEdgeToMGraph(&G, 0, 1); AddEdgeToMGraph(&G, 0, 2); AddEdgeToMGraph(&G, 1, 3); AddEdgeToMGraph(&G, 1, 4); int visited[MAX_VERTEX_NUM] = {0}; DFSTraverseMGraph(G, 0, visited); ALGraph G; InitALGraph(&G); AddVertexToALGraph(&G, 1); AddVertexToALGraph(&G, 2); AddVertexToALGraph(&G, 3); AddVertexToALGraph(&G, 4); AddVertexToALGraph(&G, 5); AddEdgeToALGraph(&G, 0, 1); AddEdgeToALGraph(&G, 0, 2); AddEdgeToALGraph(&G, 1, 3); AddEdgeToALGraph(&G, 1, 4); int visited[MAX_VERTEX_NUM] = {0}; DFS(&G, 0, visited); return 0; } ``` 这里实现了两种的表示方法:邻接矩阵和邻接表,分别对应 `MGraph` 和 `ALGraph` 结构体。其,邻接矩阵使用二维数组表示,邻接表使用链表表示。在添加顶点和边的函数,都是将数据存储到对应的结构体,同时更新顶点数和边数。在深度优先遍历函数,使用递归的方式遍历,标记已访问的节点,避免重复访问

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值