算法导论 22.4拓扑排序 22.4-1课后题简单实现

针对算法导论P356页的拓扑排序伪代码结合课后22.4.1进行简单实现和练习:

头文件对图22-8进行了描述:为了方便利用邻接矩阵表示,另一个对应图中各个节点上的字符

#include <iostream>
#include <map>
#include <vector>
using namespace std;
const vector<vector<int>> hoge
{ {	0,	0,	0,	0,	1,	1,	0,	0,	0,	0,	0,	1,	0,	0 },
 {	0,	0,	1,	0,	1,	0,	0,	0,	1,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	1,	1,	0,	0,	1,	0,	0,	0,	0 },
 {	0,	0,	1,	0,	0,	0,	1,	0,	0,	0,	0,	0,	0,	1 },
 {	0,	0,	0,	0,	0,	0,	0,	1,	0,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	1,	0,	0,	0,	1,	0 },
 {	0,	0,	0,	0,	0,	1,	0,	0,	0,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	1,	0,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	1,	1,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	1 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	1,	0,	0,	0,	0 },
 {	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0 },
};
const vector<char> cat{ 'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };

拓扑排序算法:拓扑排序函数返回为一个链表

  1. 利用深度递归搜索计算出每个节点的邻接链表扫描完成的时间,记为u.f
  2. 当每个节点的u.f值被计算出来后,将其节点插入链表头
  3. 返回该列表
#include "topSort.h" //上面那个头文件
#include <list>
#include <forward_list>

/// @brief
/// WHITE:节点初始颜色
/// GRAY:节点被发现
/// BLANK:节点邻接链表被遍历完成 对应邻接矩阵一行被遍历完成

enum Color
{
	WHITE,
	GRAY,
	BLANK
};
/// @brief
///time:时间戳 深度递归里面的时间戳,定义全局方便
int time = 0;
/// @brief
/// 定义节点信息
/// cl:当前状态
/// d:节点第一次被发现的时间
/// f:节点邻接链表扫描完成后的时间
struct MM
{
	Color cl;
	int d;
	int f;
};
/// @brief
/// @param hoge:图的邻接矩阵
/// @param u:节点集合
/// @param p:当前节点在集合的位置
void dfs_visit(vector<vector<int>> hoge, vector<MM>& u, int p, forward_list<char>& Topological_sort)
{
	++time;
	u[p].d = time;
	u[p].cl = GRAY;
	for (size_t i = 0; i < hoge[p].size(); i++)
	{
		if (hoge[p][i] == 1)
		{
			if (u[i].cl == WHITE)
			{
				//祖先 未实现
				dfs_visit(hoge, u, i, Topological_sort);
			}
		}
	}
	u[p].cl = BLANK;
	++time;
	u[p].f = time;
	/// @brief 当每次完成的时候,插入该节点在链表前端
	Topological_sort.push_front(cat[p]);
}
/// @brief 和dfs_visit共同组成深度递归遍历
/// @param hoge
/// @param u
/// @param p
void dfs(vector<vector<int>> hoge, vector<MM>& u, int p, forward_list<char>& Topological_sort)
{
	for (auto& i : u)
	{
		i.cl = WHITE;
		//qianqv
	}
	for (size_t i = 0; i < u.size(); i++)
	{
		if (u[i].cl == WHITE)
		{
			dfs_visit(hoge, u, i, Topological_sort);
		}
	}
}

/// @brief 拓扑排序函数,定义链表Topological_sort1将其置入DFS函数中,保存结果
forward_list<char> Topological_sort(vector<MM>& a)
{
	forward_list<char> Topological_sort1;
	dfs(hoge, a, 0, Topological_sort1);
	return Topological_sort1;
}
int main()
{
	vector<MM> a(hoge.size());
	/// @brief 拓扑排序  DFS的利用链表保存结果
	/// @return
	auto ans_sim = Topological_sort(a);
	for (auto& i : ans_sim)
	{
		cout << i << '\t';
	}
	cout << endl;
	/// @brief 打印个直观的结果
	/// @return
	map<int, pair<char, int>> ans;
	for (size_t i = 0; i < a.size(); i++)
	{
		ans.insert({ a[i].f,{cat[i],a[i].d} });
	}
	for (auto i = ans.rbegin(); i != ans.rend(); i++)
	{
		cout << i->second.first << '(' << i->second.second << ',' << i->first << ')' << "->";
	}
}

输出结果:

P(27,28)->N(21,26)->O(22,25)->S(23,24)->M(1,20)->R(6,19)->Y(9,18)->V(10,17)->X(15,16)->W(11,14)->Z(12,13)->U(7,8)->Q(2,5)->T(3,4)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值