图——拓扑排序(代码超详细注释哦)
程序员文章站
2022-03-14 11:01:25
...
拓扑排序可以帮助我们找到时间发生的顺序,即是先穿外套还是先穿内衣。拓扑排序的原理思想很简单,即先建立一个邻接表,临界表中记录有各个顶点的入度,我们只要一次找到入度变为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;
}
上一篇: Java虚拟机学习 - 对象访问
下一篇: Java虚拟机的具体详解