AOV拓扑排序

拓扑排序思路

1.统计所有节点的入度
2.把所有入度为0的节点入栈
3.在栈不为空的条件下把栈顶元素一个一个的弹出,并把与此节点相连的节点(即此节点指向的节点)的入度减一,再判断入度减一的节点的入度是否为0,如果为0就把此节点入栈

代码思想

1.新建node类,包含节点数值和它的指向(这里直接用list集合替代链表了)
2.一个数组包含node(这里默认编号较集中)。初始化,添加每个节点指向的时候同时被指的节点入度+1!(A—>C)那么C的入度+1;
3.扫描一遍所有node。将所有入度为0的点加入一个栈(队列)。
4.当栈(队列)不空的时候,抛出其中任意一个node(栈就是尾,队就是头,顺序无所谓,上面分析了只要同时入度为零可以随便选择顺序)。将node输出,并且node指向的所有元素入度减一。如果某个点的入度被减为0,那么就将它加入栈(队列)。
5.重复上述操作,直到栈为空。
这里主要是利用栈或者队列储存入度只为0的节点,只需要初次扫描表将入度为0的放入栈(队列)中。

例题
输入描述
首先输入图中顶点个数和边的条数;
输入顶点的信息(字符型);
输入各顶点的入度;
输入各边及其权值。
输出描述
输出AOV网的拓扑序列(顶点信息),以空格隔开,最后一个顶点后面有空格,如果AOV网存在回路,输出"有回路"的信息,占一行。
输入样例
6 9
A B C D E F
3 0 1 3 0 2
1 0
1 3
2 0
2 3
3 0
3 5
4 2
4 3
4 5
输出样例
B E C D F A

#include <iostream>
#include<queue>
using namespace std;
 
struct Arcnode
{
    int adjvex;
    Arcnode* next;
};
 
struct Vertexnode
{
    int in;
    char vertex;
    Arcnode* firstedge;
};
 
const int Maxsize = 20;
 
class ALgraph
{
public:
   ALgraph(char a[], int n, int e);
   ~ALgraph();
   void TopSort();
private:
   Vertexnode adjlist[Maxsize];
   int vertexnum;
   int arcnum;
};
 
ALgraph::ALgraph(char a[], int n, int e)
{
   vertexnum=n;arcnum=e;
   for(int i=0;i<vertexnum;i++)//顶点初始化
   {
    adjlist[i].vertex=a[i];
    adjlist[i].firstedge=NULL;
   }
   for (int i=0;i<vertexnum;i++)//输入各顶点入度
   cin>>adjlist[i].in;
   Arcnode* s=NULL,*r=NULL;
   for (int k=0;k<arcnum;k++)//尾插法
   {
     int i, j;
     cin>>i>>j;
     s=new Arcnode;
     s->adjvex=j;
     s->next=adjlist[i].firstedge;
     adjlist[i].firstedge=s;
  
 }
 
}
 
ALgraph::~ALgraph()
{
   int i;
   Arcnode* p;
   for(i=0;i<vertexnum;i++)
   {
    p=adjlist[i].firstedge;
    while(p)
   {
    Arcnode* q=p;
    p=p->next;
    delete q;
   }
 }
 
}
 
void ALgraph::TopSort()
{
    int i, j, k, count = 0;
 
    char b[Maxsize];
    int l= 0;
    queue<int> S;
    Arcnode* p = NULL;
 
    for(i= 0;i<vertexnum;i++)
    {
      if (adjlist[i].in==0) S.push(i);
    }
    while(!S.empty())
    {
      j=S.front();
      S.pop();
      b[l]=adjlist[j].vertex;
       l++;
       count++;
       p=adjlist[j].firstedge;
 
     while(p!=NULL)
     {
       k=p->adjvex;
       adjlist[k].in--;
       if (adjlist[k].in==0) S.push(k);
       p=p->next;
  }
 
 }
     if (count < vertexnum) cout << "有回路";
    else
    {
    for (int i=0;i<l;i++)
    {
     cout << b[i] << ' ';
    }
 }
}
 
int main()
{
 int i, n, m;
 
 cin >> n >> m;
 
 char* b = new char[n];
 
 for (i = 0; i < n; i++)
 {
  cin >> b[i];
 }
 
 ALgraph al(b, n, m);
 
 al.TopSort();
 
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛int i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值