• AOV拓扑排序实验-2-AOV类的实现


    下面是这个类的实现代码:

      1 //这只是一个基本的框架,没有封装
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<malloc.h>
      5 #include<cstring>
      6 #include<queue>
      7 #include<algorithm>
      8 using namespace std;
      9 struct point
     10 {
     11     int vertex;//顶点
     12     point* next;
     13 };
     14 
     15 class AOV
     16 {
     17     private:
     18     int* ok;
     19     int* indegree;//入度
     20     point* aim;//邻接表
     21     bool n_hasvalue;
     22     int n;
     23 
     24     public:
     25     int* ans;
     26     AOV(int maxn,int point_num);//构造函数原型
     27     AOV():AOV(50,50){};//直接构造函数
     28     AOV(int maxn);//容器型构造参数
     29     void maxpoint(int p);
     30     int readin();
     31     int* topo_sort();
     32 };
     33 
     34 void AOV::maxpoint(int p)
     35 {
     36     if(n_hasvalue==true)
     37     {
     38         printf("Sorry n had value,ERROR!
    ");
     39         return;
     40     }
     41     n=p;
     42     n_hasvalue=true;
     43     return;
     44 }
     45 
     46 AOV::AOV(int maxn)//容器型构造参数
     47 {
     48     ans=new int[maxn];
     49     ok=(int*)new int[maxn];
     50     memset(ok,0,sizeof(int)*maxn);
     51     //这里的重置不能写成sizeof(ok);这是最后的bug,查了好长时间
     52     indegree=new int[maxn];
     53     aim=new point[maxn];
     54     n_hasvalue=false;
     55 }
     56 //maxn是AOV容器的大小,point_num则是顶点数,分离是为了留一些重用的余地
     57 AOV::AOV(int maxn,int point_num)
     58 {//maxn描述可能使用到的最大的顶点数量
     59     ans=new int[maxn];
     60     ok=(int*)new int[maxn];
     61     memset(ok,0,sizeof(int)*maxn);
     62     indegree=new int[maxn];
     63     aim=new point[maxn];
     64     n_hasvalue=true;
     65     n=point_num;
     66 }
     67 
     68 int AOV::readin()
     69 {
     70     if(n_hasvalue==false){printf("n do not has value!
    ");return 0;}
     71     memset(indegree,0,sizeof(int)*(n+1));
     72     for(int i=0;i<n;i++)
     73     {
     74         aim[i].next=NULL;
     75         aim[i].vertex=i;
     76     }
     77     //初始化
     78     int a,b;//这里有说明具体的使用方法,可以将说明注释掉
     79     //printf("Please input pairs of numbers, which from 0 to n-1, to describe the relationship.
    ");
     80     //printf("When there is a pair of numbers consists of two 0,then input will stop.
    ");
     81     while(cin>>a>>b)
     82     {//a->b
     83         if(a==0&&b==0)break;//映射关系的结束标志是两个0
     84         if(a>=n||b>=n||a<0||b<0){printf("Data error
    ");continue;}
     85         indegree[b]++;//入度加1
     86         point* temp=&aim[a];
     87         while(temp->next!=NULL)temp=temp->next;
     88         //找到存有指向结点链表的末端
     89         temp->next=(point*)malloc(sizeof(point));
     90         temp=temp->next;//进入新的point点
     91         temp->vertex=b;//a->b
     92         temp->next=NULL;
     93     }//完成邻接表的构建
     94     return 0;
     95 }
     96 
     97 int* AOV::topo_sort()
     98 {
     99 //    for(int i=0;i<n;i++)
    100 //    {
    101 //        printf("vertex %d indegree %d points to:",aim[i].vertex,indegree[i]);
    102 //        point* temp=&aim[i];
    103 //        while(temp->next!=NULL)
    104 //        {
    105 //            temp=temp->next;
    106 //            printf("%d ",temp->vertex);
    107 //        }
    108 //        printf("
    ");
    109 //    }
    110     queue<int> psd;
    111     int cur=0;
    112     int num=n;
    113     while(1)
    114     {
    115         if(num)
    116         {
    117             for(int i=0;i<n;i++)
    118             {
    119                 if(ok[i])continue;
    120                 if(indegree[i]==0)
    121                 {
    122                     psd.push(i);
    123                     ok[i]=1;
    124                     num--;
    125                 }
    126             }//检查所有入度0的顶点并入队,留下入队标记
    127         }
    128         if(psd.empty())break;//队列为空则排序结束
    129         int p=psd.front();psd.pop();
    130         point* temp=&aim[p];
    131         ans[cur++]=p;//也可以写成ans[cur++]=aim[i].vertex;
    132         //printf("%d ",p);
    133         //提出结点并排序
    134         while(temp->next!=NULL)
    135         {
    136             temp=temp->next;
    137             indegree[temp->vertex]--;
    138         }//去掉相关有向边
    139     }
    140     //printf("
    
    cur->%d
    ",cur);
    141     return ans;
    142 }
    143 //下面是具体应用的代码
    144 int main()
    145 {
    146     freopen("input.txt","r",stdin);
    147     //freopen("ans.txt","w",stdout);
    148     int mp;
    149     cin>>mp;
    150     AOV cyc(30,mp);
    151     cyc.readin();
    152     int* temp=cyc.topo_sort();
    153     for(int i=0;i<mp;i++)
    154     {
    155         printf("%-3d",temp[i]);
    156     }
    157     return 0;
    158 }

    能力太低,不会写C++模板,所以只写了一个int型的类。可以考虑在以后的应用过程中采取映射的方式模拟非int型数据的排序。

    其中input.txt中的输入信息是:

    11
    0 8
    0 2
    1 2
    1 4
    2 3
    3 5
    3 7
    3 9
    3 10
    4 6
    6 10
    8 9
    8 3
    0 0

    得到的运行结果是:

    0  1  8  2  4  3  6  5  7  9  10

    该类型的容错性还没有来得及加强,鲁棒性比较弱,只是个初级的实验代码,数据结构考虑进一步优化。

  • 相关阅读:
    结队项目----第一次作业
    小学四则运算(2.0版本)
    小学算法(四则运算)
    (读书笔记)基于CMMI的软件工程及实训指导------第一章软件工程基础
    数学建模------线性规划
    初出茅庐-----微信好友分析与微信机器人
    初出茅庐----数据库的学习应用
    初出茅庐---程序测试与爬虫
    初出茅庐----体育竞技分析
    Unity使用小剧场—创建的按钮On Click()只有MonoScript怎么办
  • 原文地址:https://www.cnblogs.com/savennist/p/12290303.html
Copyright © 2020-2023  润新知