输出所有可能的拓扑排序

这篇具有很好参考价值的文章主要介绍了输出所有可能的拓扑排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

对于一个有向无环图

由某个集合上的一个偏序得到该集合上的一个全序的操作过程称为拓扑排序。

通俗易懂的说就是,想要的到一个有先后顺序的序列。

比如要上课,要先学了一年级的数学,才能学二年级的数学课一样。但学习几年级的语文课,对你要学习数学课没有影响。

想要得到该图的拓扑排序的一种可能,步骤:

(1) 在有向图中选一个没有前驱的顶点且输出之。

(2) 从图中删除该顶点和所有与他连接的边。

重复上述两步,直至全部顶点均已输出,或者当前图不存在无前驱的顶点为止,后一种情况说明有向图中存在环。

 这种方法通过DFS就可以很简单的就得到一个拓扑排序。

那要得到所有可能的拓扑排序要怎么做呢?

可以用DFS+回溯法 来得到

回溯算法在数据结构中是一种常用的算法,也是一种暴力求解法,基本思想,选择一条路一步一步走,当走不通的时候或者已经求得正确的结果,返回上一步,接着选择另一条路走,直到遍历完所有节点。问题的解通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。

这里定义了一个成员变量answer字符串,用来存储得到的答案。

我采用邻接矩阵的存储方式:

下面是拓扑排序的代码,注释超详细。

bool graph::order(int i ,int pos)	//得到的answer是否符合拓扑排序的顺序
{
	for(int j=0; j<pos; j++)		//对answer中顺序检查
	{
		for(int k=0; k<dot_num; k++)		//找到answer【j】对应的点的索引
		{
			if(answer[j]==dot[k])
			{
				if(side[i][k]==1)		//如果answer中出现不符合顺序的两个点,则返回0
				{
					return 0;
				}
			}
		}
	}
	return 1;
}
void graph::topolgical_dfs(int pos)		//拓扑排序专用dfs,第pos-1次递归,当pos+1=点数时,完成一条线路的深度搜索,及拓扑排序递归
{
	if(pos==dot_num)            //搜索到了所有的点
	{
		cout<<answer<<endl;
	}
	else
	{
		for(int i=0; i<dot_num; i++)		//对每个点都进行搜索
		{
			if(tag[i]==0 && order(i,pos))	//该店没被访问,并且第i个点在answer中pos的位置符合拓扑排序
			{
				tag[i]=1;
				answer[pos]=dot[i];
				topolgical_dfs(pos+1);      //从当前点进行下一次搜索
				tag[i]=0;					//可以回溯
			}
		}
	}

}

完整代码,附带很多无效的东西,(为了完成老师的任务)

#include <iostream>
using namespace std;
#define max 100
class graph
{
	public:
		int  dot_num;
		char dot[max];
		bool tag[max];
		int side[max][max];
		int out_d[max],in_d[max];
		string answer;
		graph()
		{
			cout<<"input the number of dot:";
			int n;
			cin>>n;							//输入点的个数
			dot_num=n;
			for(int i=0; i<n; i++)			//加入点
			{
				char dian;
				cout<<"the name of dot(char)"<<i+1<<":";
				cin>>dian;
				answer+=dian;		//初始化answer
				dot[i]=dian;		//设置点
				out_d[i]=0;			//出度设为0
				in_d[i]=0;			//入度设为0
				tag[i]=0;			//标志设为0
				for(int j=0; j<n; j++)
					side[i][j]=0;
			}
			cout<<"input the side(input 0 to end):"<<endl;
			string s;
			while(1)							//加入边,格式:ab(为从点a到点b的边)
			{
				cin>>s;
				if(s=="0")
					break;
				for(int i=0; i<n; i++)
				{
					if(s[0]==dot[i])
					{
						for(int j=0; j<n; j++)
						{
							if(s[1]==dot[j])
							{
								side[i][j]=1;		//边设为1
								out_d[i]=1;			//出度设为0
								in_d[j]=1;			//入度设为1
							}
						}
					}
				}

			}

		}
		void set_tag_0(); 					//全部标志置为0
		void DFS(int pos); 					//深度优先搜索
		bool order(int i ,int j);			//判断拓扑排序是否符合顺序
		void topolgical_dfs(int pos);		//拓扑排序专用DFS
		bool no_loop();						//判断有没有环
		void all_topolgical_sort();			//输出所有拓扑排序
};
void graph::set_tag_0()
{
	for(int i=0; i<dot_num; i++)
		tag[i]=0;
}
void graph::DFS(int pos)					//从dot【pos】开始深度优先遍历
{
	tag[pos]=1;
	for(int j=0; j<dot_num; j++)
	{
		if(side[pos][j]==1)
		{
			if(tag[j]==0)
				DFS(j);
		}
	}
}
bool graph::no_loop()
{
	for(int i=0; i<dot_num; i++)	//每个点都找有没有环
	{
		set_tag_0();
		DFS(i);			//对当前点进行DFS
		for(int j=0; j<dot_num; j++)
		{
			if(side[j][i]==1)		//存在 j 点到 i 点的边 
			{
				if(tag[j]==1)	//并且从 i 点可以访问到 j 点
				{
					return 0;
				}
			}
		}
	}
	return 1;
}
bool graph::order(int i ,int pos)	//是否符合拓扑排序的顺序
{
	for(int j=0; j<pos; j++)		//对answer中顺序检查
	{
		for(int k=0; k<dot_num; k++)		//找到answer【j】对应的点的索引
		{
			if(answer[j]==dot[k])
			{
				if(side[i][k]==1)		//如果answer中出现不符合顺序的两个点,则返回0
				{
					return 0;
				}
			}
		}
	}
	return 1;
}
void graph::topolgical_dfs(int pos)		//第pos-1次递归,当pos+1=点数时,完成一条线路的深度搜索,及拓扑排序递归
{
	if(pos==dot_num)
	{
		cout<<answer<<endl;
	}
	else
	{
		for(int i=0; i<dot_num; i++)		//对每个符合要求的点,访问
		{
			if(tag[i]==0 && order(i,pos))	//没被访问,并且该字母不在字符串中
			{
				tag[i]=1;
				answer[pos]=dot[i];
				topolgical_dfs(pos+1);
				tag[i]=0;					//可以回溯
			}
		}
	}

}
void graph::all_topolgical_sort()
{
	if(no_loop())				//不存在环,才开始找拓扑排序
	{
		set_tag_0();
		topolgical_dfs(0);		//从0开始构造

	}
	else
		cout<<"there is loop in this graph."<<endl;

}
int main(void)
{
	graph mygraph;
	mygraph.all_topolgical_sort();
	return 0;
}

通过输入节点及边创建一个图。当该图有环时,输出有环。

输出所有可能的拓扑排序文章来源地址https://www.toymoban.com/news/detail-485599.html

到了这里,关于输出所有可能的拓扑排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】图的应用:最小生成树;最短路径;有向无环图描述表达式;拓扑排序;逆拓扑排序;关键路径

    目录 1、最小生成树 1.1 概念  1.2 普利姆算法(Prim) 1.3 克鲁斯卡尔算法(Kruskal)  2、最短路径 2.1 迪杰斯特拉算法(Dijkstra) 2.2 弗洛伊德算法(Floyd)  2.3 BFS算法,Dijkstra算法,Floyd算法的对比 3、有向无环图描述表达式 3.1 有向无环图定义及特点 3.2 描述表达式 4、拓扑排序

    2024年02月07日
    浏览(34)
  • 有向图的拓扑排序

    拓扑排序 。任意给定一个有向图,设计一个算法,对它进行拓扑排序。拓扑排序算法思想:a.在有向图中任选一个没有前趋的顶点输出;b.从图中删除该顶点和所有以它为尾的弧;c.重复上述a、b,直到全部顶点都已输出,此时,顶点输出序列即为一个拓朴有序序列;或者直到

    2024年02月09日
    浏览(35)
  • 2023-8-29 有向图的拓扑排序

    题目链接:有向图的拓扑排序

    2024年02月11日
    浏览(29)
  • 教学计划编制问题(数据结构 有向图 拓扑排序)

     本文对以下教学计划编制问题的解决作出实现,主要使用c语言(带一点cpp),开发环境为codeblocks 17.12,希望对各位读者有所帮助。(源码和数据文件可在主页获取,同时还有使用视频文件压缩包,数据文件需要和exe在同一目录下,结合某读者的意见同时放到github了 ) 地址如下

    2024年02月09日
    浏览(39)
  • 【数据结构】有向无环图(AOE-网)的关键路径(C语言)

    把用顶点表示事件,用弧表示活动,弧的权值表示活动所需要的时间的有向无环图称为 边表示活动的网 ,简称 AOE-网 。 在AOE-网中存在唯一的、入度为0的顶点,称为 源点 ;存在唯一的、出度为0的顶点,称为 汇点 。从源点到汇点的最长路径长度即为完成整个工程任务所需的

    2024年02月07日
    浏览(33)
  • 有向无环图的应用—描述表达式、AOV网、AOE网

    目录 一、有向无环图描述表达式 二、拓扑排序 相关概念  实现方法  算法代码  补充 三、关键路径 相关概念  算法步骤  补充  四、总结图的应用我们都学了什么 有向无环图 :若一个有向图中不存在环,则称为有向无环图,简称DAG图。  对于一个表达式 ( (a+b)* ( b*(c+d)

    2024年02月12日
    浏览(34)
  • (Java)数据结构——图(第八节)有向无环图(DAG图)以及DAG描述表达式

    本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。 昨天复习了拓扑排序,打算写个博客,一翻数据结构的书到那,发现连着概念还有DAG图以及AOV网,于是看了看,这篇博客先来介绍有向无环图DAG。 下图一个无环的有向图乘坐有向无环图,

    2024年04月12日
    浏览(28)
  • 【海量数据挖掘/数据分析】之 贝叶斯信念网络(贝叶斯信念网络、有向无环图、贝叶斯公式、贝叶斯信念网络计算实例)

    目录 【海量数据挖掘/数据分析】之 贝叶斯信念网络(贝叶斯信念网络、有向无环图、贝叶斯公式、贝叶斯信念网络计算实例) 一、贝叶斯信念网络 1 . 属性关联 : 贝叶斯信念网络 允许数据集样本属性 之间存在依赖关系 ; 2 . 贝叶斯信念网络 表示方法 : 二、概率图模型 : 马尔

    2024年02月12日
    浏览(40)
  • 搜索与图论-有向图的拓扑序列

    有向图的拓扑序列就是图的广度优先遍历的一个应用。 若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个 拓扑序列 。(起点在终点的前面) 拓扑序列是针对有向图,无向图是没有拓扑序列的。 有向无环图一定是

    2024年02月01日
    浏览(35)
  • 二十一、搜索与图论——拓扑序列(有向图)

    拓扑序列定义: 若一个由图中所有点构成的序列 A满足:对于图中的每条边 (x,y),x在 A中都出现在 y之前,则称 A是该图的一个拓扑序列。 人话: 始终满足每条边的起点在终点前面,从前指向后。 注意:如果在有向图中构成一个环,则必定无法构成拓扑结构,也可以证明有向

    2024年02月04日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包