不想多说了,注释写的很清楚了。
// demo6.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <list>
#include <queue>
using namespace std;
class Graph
{
int n;//顶点个数
list<int> *lst;//邻接表
queue<int> qu;//把所有的入度为0的点进队
int* data;//存放入度
public:
Graph(int n)
{
this->n = n;
lst = new list<int>[n];//初始化
data = new int[n];//初始化
//初始化入度为0
for (int i = 0;i < n;i++)
data[i] = 0;
}
void add(int v,int u)//添加边
{
lst[v].push_back(u);//v,u为一个边的两个端点,v的后继是u,所以,把u push到v的后边
++data[u];//u的入度+1
}
bool topsort()//拓扑排序
{
//所以入度为0入队qu
for (int i = 0;i < n;i++)
if (data[i] == 0)
qu.push(i);
int count = 0;
//只要队列不空
while (!qu.empty())
{
int x = qu.front();//取出队列的头结点的值
qu.pop();//删除队列第一个元素
cout << x << " ";//从队列中取出一个顶点
//所有以x为起点的点入度-1
list<int>::iterator beg = lst[x].begin();//迭代器
//遍历以x开头的list,list[x]存放的是啥?是以x为起点用边连接的另一端的端点值
//我们遍历的目的,就是把他们的入度-1,因为我们要删除这个x点了
for (;beg != lst[x].end();beg++)
if (!(--data[*beg]))//如果入度-1后的入度值=0
qu.push(*beg);
//每完成一次这个操作,代表删除一个点,我们要计数一次
count++;
}
//count的作用就是看看我们删除的点够不够初始化的点,以确定是不是没有环
if (count < n)
return false;
else
return true;
}
};
int main()
{
Graph g(6);
g.add(5, 2);
g.add(5, 0);
g.add(4, 0);
g.add(4, 1);
g.add(2, 3);
g.add(3, 1);
if (g.topsort())
cout << "拓扑排序成功!";
else
cout << "拓扑排序失败!";
return 0;
}