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

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

原文地址:https://www.cnblogs.com/savennist/p/12290303.html