针对算法导论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' };
拓扑排序算法:拓扑排序函数返回为一个链表
- 利用深度递归搜索计算出每个节点的邻接链表扫描完成的时间,记为u.f
- 当每个节点的u.f值被计算出来后,将其节点插入链表头
- 返回该列表
#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)