通俗易懂的C++拓扑排序

不想多说了,注释写的很清楚了。 

// demo6.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include 
#include 
using namespace std;
class Graph
{
	int n;//顶点个数
	list *lst;//邻接表
	queue qu;//把所有的入度为0的点进队
	int* data;//存放入度
public:
	Graph(int n)
	{
		this->n = n;
		lst = new list[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::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;
}

 

你可能感兴趣的:(数据结构,c,数据结构)