首页 > 编程语言 >C++的拓扑排序实现

C++的拓扑排序实现

时间:2023-04-22 17:02:20浏览次数:41  
标签:std vecSpRes nColor 拓扑 C++ vector 排序 节点 spNode

template<typename T = CString, typename _Data = CString>
struct Union_node//!< 节点
{
Union_node() :nColor(0) {}
std::vector<Union_node*> vecNodeSon;
T key;//!< 关键数据
_Data data;//!< 卫星数据
mutable int nColor;//0:白色节点(未发现),1:灰色节点(发现),2:黑色节点(完毕)
};

template<typename T = CString, typename _Data = CString>
class TopologicalSort//!< 拓扑排序
{
using node = std::shared_ptr<Union_node<T, _Data>>;
public:
void setSpNode(const std::vector<node>& spNode) { m_vecSpNode = spNode; }
void setSpNode(std::vector<node>&& spNode) { m_vecSpNode.swap(spNode); }

/*!
* 拓扑排序
* \return 是否是有向无环图
*/
bool topologicalSort(std::vector<node>& vecSpRes) const;
private:
/*!
* 深搜,如果图规模较大,可能会栈溢出,需要用栈辅助
*/
bool dfs(const node& spNode, std::vector<node>& vecSpRes) const;
private:
std::vector<node> m_vecSpNode;//!< 所有节点
};

template<typename T, typename _Data>
bool TopologicalSort<T, _Data>::topologicalSort(std::vector<node>& vecSpRes) const
{
vecSpRes.clear();

// 将所有节点的颜色标记为白色(未发现)
for (auto spNode : m_vecSpNode)
spNode->nColor = 0;

// 对每个白色节点进行深搜
for (auto spNode : m_vecSpNode)
{
if (spNode->nColor != 0)
continue;
if (!dfs(spNode, vecSpRes))
return false;//遇到环,则返回false
}

// 拓扑排列(完成时间晚的放到前面)
std::reverse(vecSpRes.begin(), vecSpRes.end());
return true;
}

template<typename T, typename _Data>
bool TopologicalSort<T, _Data>::dfs(const node& spNode, std::vector<node>& vecSpRes) const
{
spNode->nColor = 1;//标记为灰色节点(未发现)

for (auto spSon : spNode->vecNodeSon)
{
if (spSon->nColor == 1)
return false;//!< 如果遇到了灰色节点,则表示发现了环
else if (spSon->nColor == 0)
{
if (!dfs(spSon, vecSpRes))
return false;//!< 后继节点包含环,返回false
}
}

spNode->nColor = 2;//标记为黑色节点(已完成)
vecSpRes.emplace_back(spNode);
return true;
}

标签:std,vecSpRes,nColor,拓扑,C++,vector,排序,节点,spNode
From: https://www.cnblogs.com/shizhimofa/p/17343415.html

相关文章

  • 初学者代码训练Day5(c/c++)
    打鱼还是晒网要求中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。流程图  代码1#include<iostream>2usingnamespacestd;34intmain()5{intyear=0,month=0,day=......
  • C++恶意软件开发(五)Linux shellcoding
    什么是shellcode?Shellcode通常指的是一段用于攻击的机器码(二进制代码),可以被注入到目标计算机中并在其中执行。Shellcode的目的是利用目标系统的漏洞或弱点,以获取系统控制权或执行恶意操作。它的名称来自于它经常被注入到攻击者编写的恶意软件的shell环境中,以便让攻击者可以更......
  • C语言和C++推荐书籍
    《CPrimerPlus》(第六版)作者:StephenPrata《C和指针》(第二版)作者:KennethA.Reek《C语言程序设计》(第四版)作者:谭浩强《C++Primer》(第五版)作者:Lippman,Lajoie,andMoo《EffectiveC++》(第三版)作者:ScottMeyers《STL源码剖析》作者:侯捷《深入理解C++11:C++11新特性解析与......
  • 10-1、(**) 排序函数模板
    已知主函数如程序后缀代码所示,请为其编写适当的模板函数,使主函数的bubbleSort函数可以对一个整型数组和一个浮点数数组进行输入、排序、输出操作。#include<iostream>#include<iomanip>#include<algorithm>usingnamespacestd;template<typenameT>TbubbleSort(T*p,co......
  • T233293 【模板】堆排序
    题目描述利用堆排序算法将读入的 N 个数从小到大排序后输出。输入格式第 11 行为一个正整数 N,第 22 行包含 N 个空格隔开的正整数 ai​,为你需要进行排序的数,数据保证了 Ai​ 不超过 109109。输出格式将给定的 N 个数从小到大输出,数之间空格隔开,行末换行......
  • 八大排序算法(c语言实现)
    title:八大排序算法(c语言实现)小知识:1)八大排序算法皆是内部排序。2)稳定的算法在排序的过程中不会改变元素彼此的位置的相对次序。反之不稳定的算法会经常改变这个相对次序。排序方法时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性冒泡排序O(n^2)......
  • 力扣——83.删除排序链表中的重复元素(c语言)
    title:力扣——83.删除排序链表中的重复元素(c语言)题目描述:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。示例1:输入:1->1->2输出:1->2示例2:输入:1->1->2->3->3输出:1->2->3代码如下:/***Definitionforsingly-linkedlist.*structListNode{*......
  • C语言和C++的switch语句用法
    C语言和C++的switch语句用法是相似的,但在一些细节上有所不同。在C语言中,switch语句的用法如下:switch(expression){  caseconstant1:    //dosomething    break;  caseconstant2:    //dosomething    break;  //...  ......
  • c++打卡第十二天
    一、问题描述。 二、设计思路①、我们可以从第五年往前推算,即1000=前一年剩余的钱*(1+12*0.0063),算出的结果加上一千就是前一年年初加上利息所得的总钱。②、列出五行式子就可以算出解。③、打印出程序运行结果。三、代码实现。#include<iostream>usingnamespacestd;i......
  • C++调用自定义源文件函数
    C++调用自定义源文件函数的步骤如下:在需要调用函数的源文件中包含自定义源文件的头文件。例如,如果需要调用名为myfunc.cpp的自定义源文件中的函数,则需要在调用该函数的源文件中包含myfunc.h头文件。编译自定义源文件。如果使用命令行编译,可以使用以下命令编译自定义源文件并生成......