图——拓扑排序(代码超详细注释哦)

拓扑排序可以帮助我们找到时间发生的顺序,即是先穿外套还是先穿内衣。拓扑排序的原理思想很简单,即先建立一个邻接表,临界表中记录有各个顶点的入度,我们只要一次找到入度变为0的即可。

方法如下:

敲黑板~~~~

1. 找到没有前驱结点即入度为0的顶点,输出它;

2. 与这个顶点相连的顶点的入度减一;

3. 一直重复上述两步直至所有结点都遍历了


 附上超超详细代码 ~(^-^)~

/*Graph.h
*图的出度邻接表的申明
*/

#define MAXV 1024
typedef int ElemType;

// 边表结点声明
typedef struct EdgeNode
{
	int adjVex;//边的下标
	struct EdgeNode *next;//指向下一条边
}EdgeNode;

//顶点表的结点声明
typedef struct VertexNode
{
	int in;//顶点入度
	ElemType data;
	EdgeNode *firstEdge;//指向第一条边
}VertexNode,AdjList[MAXV];

//图的整体声明
typedef struct Graph
{
	AdjList adjList;//顶点
	unsigned int numVertexes,numEdges;//顶点数和边数
}GraphAdjList,*pGraphAdjList;

/*Topological.h
*拓扑排序的代码实现
*/

#include "Graph.h"

//拓扑排序成功返回OK,失败返回ERROR
#define OK 1
#define ERROR 0


/*
*拓扑排序的函数申明
*参数为图的邻接表形式
*成功返回OK
*有环路失败返回ERROR
*/
int Topological(GraphAdjList g);

//Topological.cpp
#include <iostream>
#include "Topological.h"

using namespace std;

/*
*拓扑排序的函数实现
*参数为图的邻接表形式
*成功返回OK
*有环路失败返回ERROR
*/
int Topological(GraphAdjList g)
{
	//自定义一个简单队列用于实现结点的储存
	int Queue[MAXV];
	unsigned int front,rear;//头指针和尾指针

	front = rear = 0;//初始化
	unsigned int i;
	//第一次搜索入度为0的顶点
	for (i = 0;i<g.numVertexes&&g.adjList[i].in!= 0;i++);
	if (i==g.numVertexes) return ERROR;//找不到,退出

	//将此顶点入栈
	Queue[rear] = i;
	rear++;
	
	//关键实现代码
	for (EdgeNode *j = g.adjList[i].firstEdge;j!=NULL||front!=rear; )
	{
		//如果j为空,说明与这个顶点相连的边都处理好了
		while (j==NULL)
		{
			front++;
			if (front==rear) break;
			j = g.adjList[Queue[front]].firstEdge;
		}
		//去掉此顶点后,与此顶点相连的所有顶点入度减1
		if (j!=NULL&&(--g.adjList[j->adjVex].in)==0)
		{
			Queue[rear] = j->adjVex;
			rear++;
		}

		if (j!=NULL) j = j->next;
	}

	if (rear == g.numVertexes)
	{
		cout <<"拓扑排序成功!"<<endl;
		//执行打印的操作
		for (unsigned int i = 0;i<g.numVertexes;i++)
		{
			cout <<Queue[i]<<" "<<endl;
		}
		return OK;
	}
	else
	{
		return ERROR;
	}
}

//main.cpp
/*---------------------------------------
		这是拓扑排序的C++实现代码
----------------------------------------*/

#include <iostream>
#include "Topological.h"

using namespace std;

int main()
{
	//创一个测试的图
	GraphAdjList g;
	EdgeNode a1,a2,a3,a4,a5;
	a1.adjVex = 1;
	a2.adjVex = 2;
	a3.adjVex = 3;
	a4.adjVex = 4;
	a5.adjVex = 5;
	a1.next = &a2;
	a2.next = NULL;
	a3.next = NULL;
	a4.next = NULL;
	a5.next = NULL;
	g.adjList[0].data = 0;
	g.adjList[0].in = 0;
	g.adjList[0].firstEdge = &a1;
	g.adjList[1].data = 1;
	g.adjList[1].in = 1;
	g.adjList[1].firstEdge = &a3;
	g.adjList[2].data = 2;
	g.adjList[2].in = 1;;
	g.adjList[2].firstEdge = &a4;
	g.adjList[3].data = 3;
	g.adjList[3].in = 1;
	g.adjList[3].firstEdge = &a5;
	g.adjList[4].data = 4;
	g.adjList[4].in = 1;
	g.adjList[4].firstEdge = &a5;
	g.adjList[5].data = 5;
	g.adjList[5].in = 2;
	g.adjList[5].firstEdge = NULL;

	g.numEdges = 6;
	g.numVertexes = 6;

	Topological(g);

	system("pause");
	return 0;
}


    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/sj2050/article/details/80714708
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞