1. 程式人生 > >拓撲排序C++程式碼實現

拓撲排序C++程式碼實現

以下是原作者的程式碼,之後是改為std::stack<int> S

01.#include <iostream>  
02.using namespace std;  
03.#define MAX 10000000  
04.#define MAX_VERTEX_NUM 20  
05./*順序棧的定義*/  
06.#define Stack_Size 100  
07.typedef struct sqStack  
08.{  
09.       int *elem;  
10.       int top;  
11.       int stackSize;//棧陣列長度  
12.}sqStack;  
13.   
14.   
15./*順序棧的初始化*/  
16.void initStack_Sq(sqStack &S)  
17.{  
18.       S.elem=new int[Stack_Size];  
19.       S.top=-1;  
20.       S.stackSize=Stack_Size;  
21.}  
22./*入棧*/  
23.void push(sqStack &S,int x)  
24.{  
25.       if(S.top==Stack_Size-1)  
26.              cout<<"Stack Overflow!";  
27.       S.elem[++S.top]=x;  
28.}  
29.   
30./*出棧*/  
31.int pop(sqStack &S)  
32.{  
33.       int x;  
34.       if(S.top==-1)  
35.              cout<<"Stack Empty!";  
36.       x=S.elem[S.top--];  
37.       return x;  
38.}  
39.typedef struct EdgeNode  
40.{//邊表結點的定義  
41.    int adjvex;//存放鄰接點在頂點表中的位置  
42.    struct EdgeNode * nextedge;//指向下一個邊表結點  
43.}EdgeNode;  
44.typedef struct VexNode  
45.{//頂點表結點的定義  
46.    char vex;//存放頂點資訊  
47.    EdgeNode * firstedge;//指向第一個邊表結點  
48.    int indegree;  
49.}VexNode;  
50.typedef struct  
51.{//頂點表的定義     
52.    VexNode vexs[MAX_VERTEX_NUM];  
53.    int vexnum,edgenum;  
54.}LGraph;  
55./*構造有向圖的鄰接表*/  
56.void CreateDG_AL(LGraph &G,int n,int e)  
57.{  
58.    int i,j,k;  
59.    G.vexnum=n;  
60.    G.edgenum=e;  
61.    for(i=0;i<n;i++)  
62.    {  
63.        cin>>G.vexs[i].vex;  
64.        G.vexs[i].firstedge=NULL;//初始化為空  
65.    }  
66.    for(k=0;k<e;k++)  
67.    {  
68.        EdgeNode *p;  
69.        cin>>i>>j;  
70.        p=new EdgeNode;  
71.        p->adjvex=j;  
72.        p->nextedge=G.vexs[i].firstedge;  
73.        G.vexs[i].firstedge=p;//採用頭插法  
74.    }  
75.}  
76.//拓撲排序  
77.void TopoSort(LGraph &G)  
78.{  
79.    sqStack S;  
80.    initStack_Sq(S);  
81.    EdgeNode *p;  
82.    int count=0;  
83.    int i,j;  
84.    for(i=0;i<G.vexnum;i++)  
85.        G.vexs[i].indegree=0;//初始化為0  
86.    for(i=0;i<G.vexnum;i++)  
87.    {//計算各個頂點的入度  
88.        p=G.vexs[i].firstedge;  
89.        while(p)  
90.        {  
91.            G.vexs[p->adjvex].indegree++;  
92.            p=p->nextedge;  
93.        }  
94.    }  
95.    for(i=0;i<G.vexnum;i++)  
96.        if(G.vexs[i].indegree==0)  
97.            push(S,i);//將度為0的頂點入棧,這裡進棧的是入度為0的頂點在陣列中的位置  
98.    while(S.top!=-1)  
99.    {  
100.        j=pop(S);  
101.        cout<<G.vexs[j].vex<<" ";//將棧頂的元素出棧且輸出,即將入度為0的頂點輸出  
102.        count++;//計數器加1  
103.        p=G.vexs[j].firstedge;//讓p指向入度為0的頂點的第一個邊表結點  
104.        while(p)  
105.        {  
106.            G.vexs[p->adjvex].indegree--;//將入度為0的頂點的鄰接點的入度減1  
107.            if(G.vexs[p->adjvex].indegree==0)  
108.                push(S,p->adjvex);//度減1後的頂點如果其入度為0,則將其入棧  
109.            p=p->nextedge;  
110.        }  
111.    }  
112.    if(count<G.vexnum)  
113.        cout<<"Network G has citcuits!"<<endl;  
114.}  
115.void main()  
116.{  
117.    freopen("in.txt","r",stdin);  
118.    LGraph G;  
119.    CreateDG_AL(G,6,9);  
120.    TopoSort(G);  
121.}  


之後是自己的:

#define MAX_VERTEX_NUM 20
typedef struct EdgeNode
{//邊表節點的定義
	int adjvex;//存放臨界點在頂點表中的位置
	struct EdgeNode* nextedge;//指向下一個邊表節點
}EdgeNode;
typedef struct VexNode
{//頂點表節點定義
	char vex;//存放頂點資訊
	EdgeNode* firstedge;//指向第一個邊表節點
	int indegree;
}VexNode;
typedef struct
{
	VexNode vexs[MAX_VERTEX_NUM];
	int vertexnum,edgenum;
}LGraph;

//建立有向圖的鄰接表
void CreateDG_AL(LGraph &G,int n,int e)
{
	int i,j,k;
	G.vertexnum=n;
	G.edgenum=e;
	for(i=0;i<n;i++)
	{
		cin>>G.vexs[i].vex;
		G.vexs[i].firstedge=NULL;//初始化為空
	}
	for(k=0;k<e;k++)
	{
		EdgeNode *p;
		cin>>i>>j;
		p=new EdgeNode();
		p->adjvex=j;
		p->nextedge=G.vexs[i].firstedge;
		G.vexs[i].firstedge=p;//頭插法
	}
}
void TopoSort(LGraph &G)
{
	std::stack<int> S;
	EdgeNode* p;
	int count=0;
	int i,j;
	for(i=0;i<G.vertexnum;i++)
		G.vexs[i].indegree=0;//初始化為0
	for(i=0;i<G.vertexnum;i++)
	{//計算各個頂點的入度
		p=G.vexs[i].firstedge;
		while(p)
		{
			G.vexs[p->adjvex].indegree++;
			p=p->nextedge;
		}
	}
	for(i=0;i<G.vertexnum;i++)
		if(G.vexs[i].indegree==0)
			S.push(i);//將度為0的頂點入站,這裡進棧的是入度為0的頂點在陣列的位置
	while(!S.empty())
	{
		j=S.top();
		S.pop();
		cout<<G.vexs[j].vex<<" ";//將棧頂的元素出棧且輸出,即將入度為0的頂點輸出
		count++;//計數器加1
		p=G.vexs[j].firstedge;//讓p指向入度為0的頂點的第一個邊表節點
		while(p)
		{
			G.vexs[p->adjvex].indegree--;//將入度為0的頂點的鄰接點的入度減1
			if(G.vexs[p->adjvex].indegree==0)
				S.push(p->adjvex);//度減一後如果入度為0 則入棧
			p=p->nextedge;
		}
	}
	if(count<G.vertexnum)
	{
		cout<<"圖中有環"<<endl;
	}
}

int main()
{
	LGraph G;
	CreateDG_AL(G,6,5);
	TopoSort(G);
	return 0;
}