拓撲排序(基於鄰接表實現)

#include <iostream>
#include <stack> 
using namespace std;
#define MAX 100

typedef char VertexType; 

typedef struct ArcNode {
	 int adjvex;    				//鄰接點域,存儲該弧指向頂點的下標 (終點) 
	 struct ArcNode *next;			//指向下一條弧的指針 
	 int weight;					//權重 
}ArcNode;		//邊結構 

typedef struct VertexNode {
	VertexType data;				//數據域 
	ArcNode *firstArc;				//指向第一條依附該頂點的弧的指針 	
}VertexNode,AdjVerList[MAX];

typedef struct {
	AdjVerList vertices;				//頂點集		
	int vexnum,arcnum; 				//圖的頂點數和弧數
}ALGraph;		//圖結構

int indegree[MAX];				//每個頂點對應的入度數組 

void CreateALGraph(ALGraph *G);
void Display(ALGraph *G);
int TopoSort(ALGraph *G);
//a b c d e f g h i 
/*
a c 0
a h 0
b c 0
b d 0
b e 0
c d 0
d f 0
d g 0
e f 0
h i 0
i g 0
*/
int main()
{
	ALGraph G;	
	CreateALGraph(&G);
	//Display(&G);
	TopoSort(&G);
	return 0;
}

//求頂點位置函數
int LocateVex(ALGraph *G,VertexType v)
{
    int i;
    for(i=0;i<G->vexnum;i++)
    {
        if(G->vertices[i].data == v)
            return i;
    }
    return -1;
}

//有向無環圖 
void CreateALGraph(ALGraph *G)
{
    VertexType v1,v2;
    int w;
    ArcNode *Arc;

    cout<<"請輸入頂點數和邊數:";
    cin>>G->vexnum>>G->arcnum;


    cout<<"請輸入各頂點的數據:";     
    for(int i=0;i<G->vexnum;i++){
        cin>>G->vertices[i].data;
        G->vertices[i].firstArc = NULL;     //頂點的邊表設爲空
    }

    cout<<"請依次輸入"<<G->arcnum<<"組邊對應的兩個頂點以及權值,以空格分割:"<<endl;
    for(int k=0;k<G->arcnum;k++) {
		cin>>v1>>v2>>w;
        int i = LocateVex(G,v1);
        int j = LocateVex(G,v2);  
        Arc = new ArcNode;				//新建邊 
        Arc->adjvex = j;
        Arc->weight = w;
        Arc->next = G->vertices[i].firstArc;        
        G->vertices[i].firstArc = Arc;
    }
}

void Display(ALGraph *G)
{
    ArcNode *p;
    cout<<"編號,  頂點,   相鄰邊的頂點\n";
    for(int i=0;i<G->vexnum;i++)
    {
        cout<<i<<"\t"<<G->vertices[i].data;
        for(p=G->vertices[i].firstArc;p!=NULL;p=p->next)
            cout<<"\t"<<p->adjvex;
        cout<<endl;
    }
}


//求各頂點的入度(遍歷整個鄰接表)
void FindIndegree(ALGraph *G)
{
	int i;
	ArcNode *p;
    //初始化每個頂點的入度爲0
	for(i=0;i<G->vexnum;i++)
        indegree[i] = 0; 

    for(i=0;i<G->vexnum;i++)
    {
        p = G->vertices[i].firstArc;
        while(p)
        {
        	//將每一個臨接到的點(終點)自增 
            indegree[p->adjvex]++;
            p = p->next;
        }

        //cout<<i<<"元素的入度爲:"<<indegree[i]<<endl;
    } 
} 

//返回值的失敗與否代表該有向圖是否存在迴路
//拓撲排序 
int TopoSort(ALGraph *G)
{
	cout<<"該有向圖的一種拓撲排序結果爲:"<<endl; 
	stack<int> s;	//設置輔助棧,避免重複檢測入度爲0的頂點
	ArcNode *p;
	int i,k;
	FindIndegree(G);
	
	for(i=0;i<G->vexnum;i++)
	{
		//將入度爲0的頂點入棧
		if(indegree[i]==0)
			s.push(i); 
	}
	
	int count = 0;
	while(!s.empty())
	{
		i = s.top();
		s.pop();
		cout<<G->vertices[i].data<<" "; 	//將棧頂出棧並打印
		count++;							//統計已輸出的頂點數 
		
		p = G->vertices[i].firstArc;
		while(p!=NULL)
		{
			k = p->adjvex;
			indegree[k]--;					//i號頂點已出棧,所以將i號頂點的每個鄰接點的入度自減 
			if(indegree[k]==0)
				s.push(k);					//如果入度減爲0,則入棧
			p = p->next; 
		}
	}
	
	if(count<G->vexnum)
		return -1;							//存在迴路 
	else
		return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章