拓扑排序C++实现+实例解析(详解 兄弟们冲呀呀呀呀呀呀呀)

数据结构 专栏收录该内容
36 篇文章 0 订阅

一:引言

既然是一种排序,那么肯定是按照某种规则进行排序,那么这么想的话,先了解基本知识,再来实战演练
1. AOV网(Activity On Vertex Network)【顶点——表示活动】
是一个——有向无回路的图
顶点——表示活动
用弧——表示活动间的优先关系的有向图称为-顶点表示活动的网
即如果a->b,那么a是b的先决条件
求拓扑序列就是AOV
2.
用邻接矩阵存储时 每一列表示这个顶点的入度(有向图中)

二:上码

/* 
	1.
		AOV网(Activity On Vertex Network)【顶点——表示活动】
		是一个——有向无回路的图
		顶点——表示活动
		用弧——表示活动间的优先关系的有向图称为-顶点表示活动的网
		即如果a->b,那么a是b的先决条件
		求拓扑序列就是AOV
	2.
		用邻接矩阵存储时 每一列表示这个顶点的入度(有向图中)	
*/
#include<bits/stdc++.h>
using namespace std;

typedef struct GNode* PtrGraph;
typedef struct GNode{
	int Nv;
	int Ne;
	int Date[100][100];
}gnode;

int cnt; //统计每个结点的入度 
vector<int>v;//存入度的 
vector<int>v1;//记录拓扑序列 

//创建图
void creatrGraph(PtrGraph G){
	int N,M;
	cin >> N >> M;
	G->Nv = N;
	G->Ne = M;
	
	//矩阵初始化
	for( int i = 0; i < G->Nv; i++ ){
		for(int j = 0; j < G->Nv; j++ ){
			G->Date[i][j] = 0;
		}
	} 
	 
	//矩阵赋值
	for(int i = 0; i < G->Ne; i++ )
	{
		int a,b;
		cin >> a >> b;
		
		G->Date[a][b] = 1;//有向图	
	} 	
} 
//求取每一列的数据和即为该顶点的入度
void degree(PtrGraph G){
	
	for(int j = 0; j < G->Nv; j++ ){
	
		cnt = 0;
	
		for( int i = 0; i < G->Nv; i++ ){
			if(G->Date[i][j] == 1)
			 cnt++;
		}
	    
	    v.push_back(cnt);
	}
}  
//求拓扑序列

void topology( PtrGraph G ){
	
	queue<int>q;
	int count = 0;//用于计算度数为0的结点的个数 
	
	for( int i = 0; i < G->Nv; i++ )
	{
		if(v[i] == 0)
		q.push(i);//将入度为0的入队		
	} 
		
	//这里就是处理每次去掉一个度数为0的点和其有关系的顶点度数减一 
	while( !q.empty() ){
		
		int temp = q.front();
		q.pop();
		
        v1.push_back(temp); 
		
		count++;
		
		for( int j = 0; j < G->Nv; j++ ){//列 
			
			if( G->Date[temp][j] == 1  ){//在 temp 这一行中 等于 1的 j 需要入度减一 	
				v[j]--;//其入度减一
				
				if( v[j] == 0 ){
				q.push(j);// 将入度为0的入度 
			}
					 	
			}
		}
	} 
	
	if( G->Nv  == count ){//没有环 
		for( int i = 0; i < v1.size(); i++ )
          	cout << v1[i] << ' '; 	
	}else{
		cout << "此图有环"; 
	} 
	
	
} 


int main(){
	
	PtrGraph G = (PtrGraph)malloc(sizeof(struct GNode));
	creatrGraph(G);
	degree(G);
	topology(G);

	
} 


//5 6
//0 1
//0 2
//1 3
//2 1
//2 4
//3 4
//拓扑序列为:0 2 1 3 4

在这里插入图片描述
加油boy 冲呀

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值