AOV拓扑排序-基于十字链表实现

本文介绍了一种用于表示活动及其优先级的AOV图,详细解释了如何通过拓扑排序来判断图中是否存在环,并提供了一个实现拓扑排序的C++代码示例。

AOV:顶点:活动,弧:活动之间优先级,方便表示活动之间的先后制约关系
判断AOV有向图网中有环,生成一个线性序列,满足i到j有一条路径,且序列中i一定在j的前面,i,j均为顶点。

#include<iostream>
#include<stack>
using namespace std;
const int maxNum = 100;
typedef struct arcNode {    //弧结点类型
	int tail;				//弧尾下标
	int head;				//弧头下标
	struct arcNode*hlink;	//指针,指向同弧头的弧
	struct arcNode*tlink;	//指针,指向同弧尾的弧
}arcNode;
typedef struct vexNode
{
	char data;				//指点数据
	arcNode *firstIn;		//指针,指向第一个入弧
	arcNode *firstout;		//指针,指向第一个出弧
};
typedef struct {
	vexNode vexs[maxNum];
	int vexnum, edgenum;	//顶点数量,边数量
}OLGraph;
OLGraph g;
int topo[maxNum];
int LocateVex(char c)
{
	for (int i = 0; i < g.vexnum; i++)
	{
		if (g.vexs[i].data == c)
		{
			return i;
		}
	}
	return -1;
}
void insertedge(char a, char b)
{
	int ai = LocateVex(a);
	int bi = LocateVex(b);
	arcNode* an = new arcNode;						//生成一条新弧
	an->tlink = g.vexs[ai].firstout;		//顶点第一个出弧更新,尾插入
	an->head = bi;						//由ai->bi
	an->tail = ai;
	g.vexs[ai].firstout = an;			//顶点第一个出弧更新,尾插入
	an->hlink = NULL;
	if (g.vexs[bi].firstIn == NULL)
	{
		g.vexs[bi].firstIn = an;
	}
	else
	{
		arcNode* curArc = g.vexs[bi].firstIn;		//找到最后一个入弧
		while (curArc->hlink != NULL)
		{
			curArc = curArc->hlink;
		}
		curArc->hlink = an;
	}
}
void CreateOLGraph() {
	cout << "请输入顶点数量和边数:" << endl;
	cin >> g.vexnum >> g.edgenum;
	cout << "输入对应的顶点:" << endl;
	for (int i = 0; i < g.vexnum; i++)
	{
		cin >> g.vexs[i].data;
		g.vexs[i].firstIn = NULL;
		g.vexs[i].firstout = NULL;
	}
	cout << "输入要插入的边" << endl;
	int m = g.edgenum;
	while (m > 0)
	{
		char a, b;
		cin >> a >> b;
		insertedge(a, b);
		m--;
	}
}
bool TopologicalSort()
{
	int* indegree = new int[g.vexnum];			//入度数组
	int k=0;
	stack<int> stack;
	arcNode* an;
	//初始化入度数组
	for (int i = 0; i < g.vexnum; i++)
	{
		int m = 0;
		an = g.vexs[i].firstIn;
		while (an != NULL)
		{
			m++;
			an = an->hlink;
		}
		indegree[i] = m;
		cout << i << "的入度为:" << m<<endl;
	}
	//将入度为0的顶点索引加入栈中,当栈为空结束
	for (int i = 0; i < g.vexnum; i++)
	{
		if (indegree[i] == 0)
			stack.push(i);
	}
	while (stack.size() > 0)
	{
		int t = stack.top();
		stack.pop();
		topo[k] = t;
		//把t顶点的所有出度的顶点入度全部减一
		an = g.vexs[t].firstout;
		while (an != NULL)
		{
			indegree[an->head]--;
			if (indegree[an->head] == 0)
			{
				stack.push(an->head);
			}
			an = an->tlink;
		}
		k++;
	}
	if (k < g.vexnum)
		return false;
	else return true;
}
int main() 
{
	CreateOLGraph();
	if (TopologicalSort())
	{
		cout << "无环有向图,拓扑排序为:" << endl;
		for (int i = 0; i < g.vexnum; i++)
		{
			cout << topo[i] << " ";
		}
		cout << endl;
	}
	else 
	{
		cout << "有环有向图";
	}
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustEasyCode

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值