【C++】AOV网与拓扑排序

这篇博客详细介绍了如何使用C++实现有向图的深度优先遍历(DFS)、广度优先遍历(BFS)以及拓扑排序。通过创建邻接表结构,输入边信息,然后分别调用DFS、BFS和TopSort函数,展示从特定顶点开始的遍历序列。示例中展示了从顶点A和C出发的遍历结果,以及拓扑排序序列,验证了代码的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码实现:
输入:按顶点之间的指向输入一个有向图 如ch[0]=‘A’指向ch[3]=‘D’ 则输入 0 3
输出:由代码中指定顶点开始的深度遍历与广度遍历以及拓扑排序

#include <iostream>
using namespace std;

const int MaxSize=10;            //图的最大顶点数
int visited[MaxSize] = {0};


struct EdgeNode   //定义边表结点
{
	int adjvex;  //邻接点域
	EdgeNode *next;
	
};
template <class DataType>
struct VertexNode   //定义顶点表结点
{
	DataType vertex;
	EdgeNode *firstEdge;
	int In; 
};

template <class DataType>
class ALGraph
{
public:
	ALGraph(DataType a[ ], int n, int e);   //构造函数,建立一个有n个顶点e条边的图
	~ALGraph( );							//析构函数,释放邻接表中各边表结点的存储空间
	void DFTraverse(int v);				//深度优先遍历图
	void BFTraverse(int v);				//广度优先遍历图
	void TopSort();
private:
	VertexNode<DataType> adjlist[MaxSize];  //存放顶点表的数组
	int vertexNum, edgeNum;					//图的顶点数和边数
};

template <class DataType>
ALGraph<DataType>::ALGraph(DataType a[ ], int n, int e)
{
	int i,j,k;
	EdgeNode *s = NULL;
	vertexNum = n;  //顶点数量赋值 
	edgeNum = e;	//边数量赋值 
	for(i = 0;i<vertexNum;i++)//初始化顶点表信息 
	{
		adjlist[i].vertex = a[i];//在表中存放所有顶点信息 
		adjlist[i].firstEdge = NULL; //将所有邻边点指针置空 
		adjlist[i].In = 0; //将所有顶点入度初始化为 0 
	 } 
	 for(k = 0;k<edgeNum;k++)//初始化指向边信息 
	 {
	 	cout << "请输入两个边顶点的序号:";
	 	cin>>i>>j;//输入i号指向j号 
	 	adjlist[j].In += 1 ;
	 	s = new EdgeNode;//新建边表
	 	s->adjvex = j;//边表的邻顶点序号 
	 	s->next = adjlist[i].firstEdge; //头插法 
	 	adjlist[i].firstEdge = s;
	 }
} 

template <class DataType>
ALGraph<DataType>::~ALGraph( )
{
	EdgeNode *p = NULL, *q = NULL;
	for(int i=0;i<vertexNum;i++)	//释放所有边表结点的存储空间 
	{
		p=q=adjlist[i].firstEdge;
		while(p!=NULL)
		{
			p = p->next;
			delete q;
			q = p;
		}
	}
}

template <class DataType>
void ALGraph<DataType>::DFTraverse(int v)//有向图深度遍历 
{
	int j;
	EdgeNode *p = NULL;
	cout<<adjlist[v].vertex;
	visited[v] = 1;
	p = adjlist[v].firstEdge;	//p指向顶点v的边表 
	while(p!=NULL)//依次搜索v点的邻接点j点 
	{
		j = p->adjvex;	//j指向v的第一个邻点 
		if(visited[j]==0)DFTraverse(j);		
		p = p->next;
	 } 
} 

template <class DataType>
void ALGraph<DataType>::BFTraverse(int v)//有向图广度遍历 
{
	int w, j, Q[MaxSize];
	int front = -1, rear = -1;
	EdgeNode *p = NULL;
	cout<<adjlist[v].vertex;	//输出v点信息 
	visited[v] = 1;	//标记v点 
	Q[++rear] = v;	//v点入队 
	while(front!=rear)
	{
		w = Q[++front];	//v点出队 w=v 
		p = adjlist[w].firstEdge;	//p指向顶点v的边表 
		while(p!=NULL)
		{
			j = p->adjvex;	//j点是v点的邻点 
			if(visited[j]==0)	//若j点未被访问,将j点入队 
			{
				cout<<adjlist[j].vertex;
				visited[j] = 1;
				Q[++rear] = j;
			}
			p = p->next;
		}
	 } 
}

 template <class DataType>
void ALGraph<DataType>::TopSort()
{
	int i,j,k,count = 0;
	int S[MaxSize],top = -1;
	EdgeNode *p = NULL;
	for(i = 0;i<vertexNum;i++)
	{
		if(adjlist[i].In==0) S[++top] = i;	//寻找初始状态下入度为 0 的点 
	 } 
	 while(top!=-1)
	 {
	 	j = S[top--];
	 	cout<<adjlist[j].vertex;
	 	count++; 	//计数有多少个点已输出 
	 	p = adjlist[j].firstEdge;
	 	while(p!=NULL)	//将j点指向的所有点入度减 1,用边表遍历寻找j点通向的邻点 
	 	{
	 		k = p->adjvex;	//k为邻点 
	 		adjlist[k].In--;	//k的入度减 1 
	 		if(adjlist[k].In==0) S[++top] = k;	//如果k点入度为 0,入队 
	 		p = p->next; 
		 }
	 }
	 if(count<vertexNum) cout<<"有回路"<<endl;	//如果输出的顶点个数与存在顶点个数不相等 
	 											//说明AOV网中存在回路 
}
int main()
{
	char ch[ ]={'A','B','C','D','E','F'};
	int i;
	ALGraph<char> ALG(ch, 6, 9);
	for (int i = 0; i < MaxSize; i++)
	{
		visited[i] = 0;
	}
	cout<<"从顶点"<<ch[0]<<"进行深度优先遍历序列是:";
	ALG.DFTraverse(0);
	for (int i = 0; i < MaxSize; i++)
	{
		visited[i] = 0;
	}
	cout<<""<<endl;
	cout<<"从顶点"<<ch[2]<<"进行广度优先遍历序列是:";
	ALG.BFTraverse(2);
	cout<<""<<endl;
	cout<<"其拓扑排序是:";
	ALG.TopSort();
	cout<<endl;
	return 0;
} 

示例:
在这里插入图片描述

输入:

请输入两个边顶点的序号:1 0
请输入两个边顶点的序号:1 3
请输入两个边顶点的序号:2 0
请输入两个边顶点的序号:2 3
请输入两个边顶点的序号:3 0
请输入两个边顶点的序号:3 5
请输入两个边顶点的序号:4 2
请输入两个边顶点的序号:4 3
请输入两个边顶点的序号:4 5

输出:

从顶点A进行深度优先遍历序列是:A
从顶点C进行广度优先遍历序列是:CDAF
其拓扑排序是:ECBDAF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值