下面是这个类的实现代码:
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
该类型的容错性还没有来得及加强,鲁棒性比较弱,只是个初级的实验代码,数据结构考虑进一步优化。