zoukankan      html  css  js  c++  java
  • 图——拓扑排序(代码超详细注释哦)

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




  • 相关阅读:
    CentOS7安装MySQL5.7
    .gdbinit文件配置
    Linux 动态库加载
    GDB常用调试命令(二)
    git删除缓存区中文件
    git添加空文件夹
    Linux 打开core dump功能
    C++ 预处理器
    C++ 模板
    C++ 命名空间
  • 原文地址:https://www.cnblogs.com/sj2050/p/13413721.html
Copyright © 2011-2022 走看看