拓扑排序(队列实现)

2023-05-16

什么是拓扑排序呢?就是将一个有向无环图中所有顶点在不违反先决条件关系的前提下排成线性序列的过程称为拓扑排序。
学拓扑排序有什么用呢?当然有用啦~。比如说学校排课的时候,会考虑到有的课程需要先修。我们学完C程序设计这门课,有了编程基础,然后才能学习数据结构。大学要修很多门课程的,人为的去排课很头痛的,这时候就可以用拓扑排序解决这个问题。
拓扑排序只针对有向无环图(DAG),有两种方法可以实现,一种是队列实现,另外一种是深搜(DFS)实现。
这里先介绍队列实现的方法。
(1)从图中选择任意一个入度为0的顶点且输出
(2)从图中删掉此顶点及所有的出边,将其入度减少1
(3)回到第(1)步继续执行
图
我们对上面图进行拓扑排序,我这里采用的是邻接表储存图,贴代码。

#include<vector>
#include<iostream>
#include<queue>
using namespace std;
class Graph
{
	int v;                             //顶点个数
	vector<int> *adj;                   //邻接表
	int *indegree;                      //每个顶点的入度
public:
	Graph(int n);                       //构造函数
	~Graph();                           //析构函数
	void addEdge(int start,int end);    //添加边
	void TopsortbyQueue();              //拓扑排序
};

Graph::Graph(int n)
{
	v=n;
	adj=new vector<int>[n];    
	indegree=new int[n];
	for(int i=0;i<n;i++)             //入度初始化为0
		indegree[i]=0;
}
Graph::~Graph()
{
	delete [] adj;
	delete [] indegree;
}
void Graph::addEdge(int s,int e)
{
	adj[s].push_back(e);
	indegree[e]++;                      //入度加1
}

void Graph::TopsortbyQueue()
{
	queue<int> aqueue;                   //使用STL的队列
	int count = 0;                       //记录遍历顶点的个数
	for(int i=0;i<v;i++)
	{
		if(indegree[i]==0)               //将入度为0的顶点入队
			aqueue.push(i);
	}

	while(!aqueue.empty())				 //如果队列不空
	{
		int node = aqueue.front();       //获得队列顶部元素
		aqueue.pop();                    //队列出队
		cout<<node<<" ";                 //输出
		count++;                         //遍历到的顶点个数加1
		for(vector<int>::iterator ii=adj[node].begin();ii!=adj[node].end();ii++)
		{
			indegree[*ii]--;                              //相邻的顶点入度减1
			if(indegree[*ii]==0)                          //顶点入读减为0则入队
				aqueue.push(*ii);
		}
	}

	if(count<v)                                  //如果没有遍历全部节点说明图中有环
		cout<<"有环"<<endl;

}

int main()
{
	Graph g(9);
	g.addEdge(0,2);
	g.addEdge(0,7);
	g.addEdge(1,2);
	g.addEdge(1,4);
	g.addEdge(1,3);
	g.addEdge(2,3);
	g.addEdge(3,5);
	g.addEdge(3,6);
	g.addEdge(4,5);
	g.addEdge(7,8);
	g.addEdge(8,6);
	g.TopsortbyQueue();
	return 0;
}

运行结果
在这里插入图片描述
图的每条边处理一次,图的每个顶点访问一次,采用邻接表表示时时间复杂度为 O(n+e)。采用相邻矩阵表示时,为O(n*n)。
对DFS实现拓扑排序有兴趣的,点击:拓扑排序DFS版

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

拓扑排序(队列实现) 的相关文章

随机推荐

  • IDEA插件开发-学习

    IDEA插件资料其实挺少的 xff0c 可能我姿势不对 闲暇无事 xff0c 当作练手 这东西挺难调试的 xff0c 官方文档实在看不下去 xff0c 谷歌资料也挺少的 把下面这些东西复制进去可以当调试用了 Project project
  • 树莓派 通过opencv 调用csi摄像头

    树莓派使用csi摄像头 在设置里面打开摄像头 检测摄像头 安装opencv 读取图像测试 socket 网络传图测试 opencv多线程 取图测试 在设置里面打开摄像头 span class token function sudo span
  • Centos7.2下安装Pyspider

    本来一直使用的python3 X的 xff0c 之前一直弄的Python3 6 1 xff0c 不知道为啥 xff0c 搭建了好几次都没有成功 xff0c 不知道是什么地方的问题 xff0c 后面再找一下问题 还有就是在Windows上搭建
  • OFD版式文件的优势

    OFD版式文件的优势 OFD格式是我国自主可控的电子文件版式文档格式 在OFD格式产生之前 xff0c 电子文件存档格式并没有统一的国家或行业标准 xff0c 档案工作中普遍采用DOC WPS PPTX等流式文件格式 内容易更改 转移过程存
  • OFD是什么?

    OFD是什么 xff1f OFD格式文件介绍 OFD xff08 Open Fixed layout Document的简称 xff0c 意为开放版式文档 xff09 xff0c 是按照我国自主研发制定的版式文档格式标准 GB T 3319
  • ofd格式文件转换成pdf格式的方法

    ofd格式文件很多人还比较陌生 xff0c 很多人接收到文件都不知如何打开阅读 xff0c 把文件发给对方 xff0c 还需要对方安装个专门的阅读软件 xff0c 我们还有另一个办法 xff0c 就是将OFD文件转换为PDF格式文件 xff
  • 比较出名的导航类网站

    网址导航是把很多网站集合起来 xff0c 按照一定的条件进行分类的网站 网址导航方便网民快速找到自己需要的网站 xff0c 可以直接到需要的网站 xff0c 而不必记住各个网站的网址 现在的网址导航一般都提供自己常用的查询工具 xff0c
  • 使用NGINX作为HTTPS正向代理服务器

    简介 xff1a NGINX主要设计作为反向代理服务器 xff0c 但随着NGINX的发展 xff0c 它同样能作为正向代理的选项之一 正向代理本身并不复杂 xff0c 而如何代理加密的HTTPS流量是正向代理需要解决的主要问题 本文将介绍
  • 超级小的docker镜像

    超级小的docker镜像 xff0c 通过可用来做基础镜像或者测试使用 拉镜像尽量选择带有apline或slim标签的 xff0c 体积很小 alpine镜像官方地址 xff1a https hub docker com alpine 拉取
  • 16进制转Base64的实现原理及代码

    随着计算机技术的发展 xff0c 数据的存储和传输方式也在不断更新 xff0c 其中十六进制字符串和Base64编码是两种常见的数据表示方式 本文将介绍16进制字符串和Base64编码的原理 xff0c 并提供Java代码实现16进制字符串
  • MySQL错误-this is incompatible with sql_mode=only_full_group_by解决办法

    原因分析 xff1a 一 原理层面 这个错误发生在mysql 5 7 5 版本及以上版本会出现的问题 xff1a mysql 5 7 5版本以上默认的sql配置是 sql mode 61 ONLY FULL GROUP BY xff0c 这
  • pulsar-admin接入项目

    练手项目 第一步 xff1a 添加依赖 lt dependency gt lt groupId gt org apache pulsar lt groupId gt lt artifactId gt pulsar client admin
  • C/C++语言——函数返回临时变量、对象

    函数内部栈上创建的临时变量 临时对象 xff0c 生命周期只在函数运行期间 xff0c 函数运行结束后 xff0c 就会释放对应内存空间 错误的函数写法 int amp test1 int x 61 1 return x 错误的函数写法 i
  • VS2008——调试方法大全

    一 断点调试 总结以下VS2008的调试方法 xff0c 首先最常用的就是使用断点了 xff0c 断点分为两种 xff1a 普通断点 跟踪点 普通断点就是红色圆点 xff0c 跟踪点是红色菱形 可以通过右键设置断点相关内容 xff0c 让断
  • Effective C++——22.将成员变量声明为private

    1 一致性 xff1a 如果public中的每样东西都是函数 xff0c 就不需要思考使用的时候要不要带小括号 2 使用函数可以让成员变量的处理有更精确的控制 3 封装性 xff1a 有时候要根据不同情况修改set和get的实现方式 xff
  • Effective C++——4.确定对象被使用前已经初始化

    1 为防止有的情况下对象未初始化导致的混乱 xff0c 最佳的处理办法就是 xff1a 永远在使用对象之前先将它初始化 对于无任何成员的内置类型 xff0c 必须手工完成 2 内置类型以外的任何其他东西 xff0c 初始化责任在构造函数中
  • Effective C++——32.确定public继承是“is-a”关系

    1 is a关系的概念 xff0c 就是基类可以实现的事情 xff0c 子类就一定要能实现 如果不能实现 xff0c 可以修改设计 xff0c 比如将基类能实现 xff0c 子类却不能实现的事情派生出一个中间基类 记住一点 xff1a 1
  • Java中repaint方法清除原来图像问题

    虽然Java界面编程作用不大 xff0c 但在兴趣的驱使下还是了解了一下 xff0c 在写小程序的时候发现了repaint方法有时候会清理原来的图像 xff0c 有时候又不清理 下面贴出我通过API文档得出的结论 xff0c 以下例子窗口为
  • 怎样找回自己CSDN丢失博客?

    写博客是件很欢快的事情 xff0c 但没多久就发现自己刚写的博客丢失 xff0c 这是一件更加 欢快 的事情 百度了一下关于CSDN博客丢失的现象 xff0c 虽然不算很多 xff0c 但还是有个别人也同样发生了这样的情况 注 xff1a
  • 拓扑排序(队列实现)

    什么是拓扑排序呢 xff1f 就是将一个有向无环图中所有顶点在不违反先决条件关系的前提下排成线性序列的过程称为拓扑排序 学拓扑排序有什么用呢 xff1f 当然有用啦 比如说学校排课的时候 xff0c 会考虑到有的课程需要先修 我们学完C程序