C++拓扑排序

思想

1.先求的图中每个顶点的入度,将入度为0的顶点加入栈或者队列 F;
2.从F中取出一个顶点,输出,count++,并删除它的出边,将它邻接顶点的入度-1,并将修改后入度为0的顶点加入F;
3.重复第二步直至F为空,若count等于图的总顶点数,说明图中无环。

代码

请添加图片描述

//输入示例
// 6 7  0 1 2 3 4 5  0 1 1  0 2 3  0 4 3  1 3 5  2 3 1  3 5 4  3 4 3
#include<iostream>
#include <stack>

using namespace std;

#define MAXVEX 100

//拓扑排序用到的图与普通图结构不同,这里是有向图,且要有存储结点入度数的变量
typedef struct EdgeNode  //出边表
{
	int adjvex;  //出边顶点
	int weight;  //权重
	struct EdgeNode* next;
}EdgeNode;

typedef struct VertexNode  //顶点表
{
	int in = 0;  //入度
	int data;  //值
	EdgeNode* firstedge;  //顶点出边
}VertexNode,Adjlist[MAXVEX];

typedef struct  //有向图
{
	Adjlist adjlist;  //顶点序列
	int numVex, numEdge;
}graphAdjlist,*GraphAdjlist;


void CreatGraph(graphAdjlist &G)
{
	int f, t, w;
	cout << "输入顶点数,边数"<< endl;
	cin >> G.numVex >> G.numEdge;
	
	cout << "输入各顶点值" << endl;
	for (int i = 0; i < G.numVex; i++)
	{
		G.adjlist[i].in = 0;
		cin >> G.adjlist[i].data;
		G.adjlist[i].firstedge = nullptr;
	}
	cout << "输入各边,from to weight" << endl;

	for (int i = 0; i < G.numEdge; i++)  //输入边
	{
		cin >> f >> t >> w;
		EdgeNode* p;  //头插法
		p = new EdgeNode();
		p->adjvex = t;
		p->weight = w;
		p->next = G.adjlist[f].firstedge;
		G.adjlist[f].firstedge = p;
		G.adjlist[t].in++;
	}
	cout << "成功建立图如下:" << endl;
	for (int i = 0; i < G.numVex;i++)
	{
		EdgeNode* q;  
		q = new EdgeNode();
		cout << G.adjlist[i].data << endl;
		q = G.adjlist[i].firstedge;
		while (q != NULL)
		{
			cout << q->adjvex << " " << q->weight << "  ";
			q = q->next;
		}
		cout << endl;
	}
}

void TopuSort(graphAdjlist G)
{
	stack<int> inVex;
	int top;
	int count=0;
	int k;
	EdgeNode *e;
	for (int i = 0; i < G.numVex; i++)  //所有入度为0的点入栈
		if (G.adjlist[i].in == 0)
			inVex.push(i);
	while (!inVex.empty())  //栈不为空则
	{
		top = inVex.top();  //弹出栈顶
		inVex.pop();
		cout << G.adjlist[top].data << " ";  //输出栈顶
		count++;  //记录已生成序列总顶点数
		//对弹出顶点遍历所有邻接点,入度-1,若-1后入度为0则入栈
		for (e = G.adjlist[top].firstedge;e!=NULL; e = e->next)  
		{
			k = e->adjvex;
			if ((--G.adjlist[k].in)==0)
			{
				inVex.push(k);
			}
		}
	}
	if (count < G.numVex) //拓扑序列数小于顶点总数则说明有环
		cout << endl << "有环";
	else
		cout << endl << "无环";
}

int main()
{
	graphAdjlist G;
	CreatGraph(G);
	TopuSort(G);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值