拓扑排序
方法:
①找出一个入度为0的顶点,输出(作为序列的一个元素)
②删除顶点v及其牺牲你关掉的弧,(因而后继定点的入度为1,并可能出现新的入度为0的顶点)
③重复上述步骤①②,直到找不到入度为0的顶点为止。
(拓扑序列不唯一)
1 #include "iostream" 2 #include "stack" 3 using namespace std; 4 5 const int MaxNumVertex = 20; //最大顶点数 6 const int infinity = 65535;//无穷大 7 typedef int elementtype; //elementtype 为int 型 8 class graph{ 9 public: 10 graph(); 11 ~graph(); 12 elementtype insertvertex(elementtype v); //在图中增加一个顶点 13 elementtype insertedge(elementtype v,elementtype u);//在图中增加一条从v顶点到u顶点的弧 14 elementtype firstadj(elementtype v);//求图g中顶点v的第一个邻接点 15 elementtype nextadj(elementtype v,elementtype m);//求图中顶点v的m邻接点之后的邻接点 16 elementtype degree(elementtype v);//求图中顶点v的度数 17 bool ToplogicalSort();//拓扑排序 18 elementtype FindDegree(elementtype ind[]);//各顶点的入读存放于入度数组中 19 elementtype create();//创建图 20 int CurrentVertex;//当前顶点数 21 22 private: 23 elementtype vertex[MaxNumVertex];//顶点表 24 elementtype edge[MaxNumVertex][MaxNumVertex];//图中弧的类型 25 26 }; 27 28 /* 29 *初始化 30 */ 31 graph::graph() 32 { 33 CurrentVertex = 0; 34 int i,j; 35 for (i=MaxNumVertex-1;i>=1;i--) 36 { 37 for (j=MaxNumVertex-1;j>=1;j--) 38 { 39 edge[i][j] = 0; 40 41 } 42 } 43 44 } 45 46 /* 47 *在图中增加一个顶点 48 */ 49 elementtype graph::insertvertex(elementtype v) 50 { 51 //判断这个顶点是否已经存在 52 int i; 53 bool flags = true; 54 for(i=1; i<=CurrentVertex; i++) 55 { 56 if(vertex[i]==v) 57 { 58 flags = false; 59 break; 60 } 61 } 62 63 if(flags) 64 { 65 CurrentVertex++; 66 vertex[CurrentVertex] = v; 67 }else{ 68 cout<<v<<"顶点已经存在!"<<endl; 69 } 70 return 0; 71 } 72 73 /* 74 *在图中增加一条从v顶点到u顶点的弧 75 */ 76 elementtype graph::insertedge(elementtype v,elementtype u) 77 { 78 if(edge[v][u]!=0) 79 { 80 cout<<v<<"->"<<u<<"这条弧弧已经存在!"<<endl; 81 }else{ 82 edge[v][u] = 1; 83 } 84 return 0; 85 } 86 87 88 /* 89 *求图中顶点v的第一个邻接点 90 */ 91 elementtype graph::firstadj(elementtype v) 92 { 93 int u,i; 94 bool flags = true;//用于判断是否存在邻接点 95 for(i=1;i<=CurrentVertex;i++) 96 { 97 if(edge[v][i]!=0){ 98 u = i; 99 flags = false; 100 break; 101 } 102 } 103 if(flags) u = 0;//邻接点不存在 104 return u; 105 } 106 107 /* 108 *求图中顶点v的m邻接点以后的邻接点 109 */ 110 elementtype graph::nextadj(elementtype v,elementtype m) 111 { 112 int i,u; 113 bool flags = true; 114 for(i=m+1;i<=CurrentVertex;i++) 115 { 116 if(edge[v][i]!=0) 117 { 118 u = i; 119 flags = false; 120 break; 121 } 122 } 123 if(flags) u = 0;//邻接点不存在 124 return u; 125 } 126 127 /* 128 *求图中顶点v的入度数 129 */ 130 elementtype graph::degree(elementtype v) 131 { 132 int i,num = 0; 133 for (i=1;i<=CurrentVertex;i++) 134 { 135 if(edge[i][v]!=0)num++; 136 } 137 return num; 138 } 139 140 /* 141 *每个顶点的入度 142 */ 143 elementtype graph::FindDegree(elementtype ind[]) 144 { 145 int i; 146 for(i=1;i<=CurrentVertex;i++) 147 { 148 ind[i] = degree(i); 149 } 150 return 0; 151 } 152 153 /* 154 *拓扑排序 155 */ 156 bool graph::ToplogicalSort() 157 { 158 int i,x,w,v; 159 stack<int> s;//定义并初始索要用到的栈 160 elementtype ind[MaxNumVertex];//求各顶点的入度存放于入度数组ind中 161 FindDegree(ind);// 162 for(i=1;i<=CurrentVertex;i++)//将入度为0的顶点入栈 163 { 164 if(ind[i]==0) 165 { 166 s.push(i); 167 v = i; 168 } 169 } 170 int count =0; 171 cout<<"ToplogicalSort:"; 172 while(!s.empty()) 173 { 174 x = s.top(); 175 count++; 176 if(count<CurrentVertex)cout<<x<<"->"; 177 else cout<<x<<endl; 178 s.pop(); 179 w = firstadj(x); 180 while(w!=0) 181 { 182 183 if(!(--ind[w])) 184 { 185 s.push(w); 186 } 187 w = nextadj(x,w); 188 } 189 190 } 191 if(count<CurrentVertex)return false;//产生有回路的标志 192 else return true; 193 return 0; 194 } 195 196 elementtype graph::create() 197 { 198 int i,numv,v,u; 199 cout<<"input numvertex(顶点数):"; 200 cin>>numv; 201 cout<<"input vertex(顶点):"; 202 for(i=1;i<=numv;i++) 203 { 204 cin>>v; 205 insertvertex(v); 206 } 207 208 cout<<"input num(u,v)(弧的数目):"; 209 cin>>numv; 210 211 for(i=1;i<=numv;i++) 212 { 213 cout<<"u->v:"; 214 cin>>u>>v; 215 insertedge(u,v); 216 } 217 cout<<endl; 218 return 0; 219 } 220 graph::~graph() 221 { 222 } 223 224 int main() 225 { 226 graph g; 227 g.create(); 228 g.ToplogicalSort(); 229 return 0; 230 }