首页 > 技术文章 > 6)图[3]拓扑排序算法

minmsy 2015-12-01 17:15 原文

拓扑排序

方法:

①找出一个入度为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 }

推荐阅读