图的拓扑排序

注意的问题:
1、几个结构体的定义是相关联的,它们的先后顺序不能乱。
2、链表的每个节点是需要动态申请空间的。
#include <stdlib.h>
#include <iostream>

#define NUM 20  //最大顶点数
using namespace std;

struct EdgeNode //边节点
{
	int index; //指向定点的索引
	EdgeNode *next;	 
};

struct VertexNode  //顶点结构
{
	int indegree; //入度
	char name[10]; //顶点的名称
	EdgeNode *link;
};

struct Graph  //定义图结构
{
	VertexNode G[NUM];
	int numVertexes,numEdges; 
};

Graph CreatGraph();  //创建图
void  OutputGraph(Graph g);  //图的输出
void  TopoSort(Graph g);   //拓扑排序

int main()
{
	Graph g=CreatGraph();

	cout<<"图的输出如下:"<<endl;
	OutputGraph(g);

	cout<<"排序结果如下:"<<endl;
	TopoSort(g);

	cout<<endl;
	system("pause");
	return 0;
}


Graph CreatGraph()
{
	Graph g;
	cout<<"输入顶点数和边数(输入格式为a b):"<<endl;
	cin>>g.numVertexes>>g.numEdges; 

	int i,j;
	cout<<"请输入顶点的值(输入格式为C1 C2 C3...):"<<endl;
	for(i=0;i<g.numVertexes;i++)  // 顶点结构体的初始化
	{  
		cin >> g.G[i].name;
		g.G[i].indegree=0;
		g.G[i].link=NULL;	
	}

	cout<<"请输入边的起始和指向序号(输入格式为a b):"<<endl;
	int start,end;
	for (int k=0; k<g.numEdges;k++)  //形成每个顶点后面的邻接表(使用链表的头插法)
    {
        cin>>start>>end;  
        EdgeNode *temp = (EdgeNode *)malloc(sizeof(EdgeNode));  
		temp->index = end-1;  //因为数组下标从0开始,实际数据从1开始
        temp->next = g.G[start-1].link;  
        g.G[start-1].link = temp;   
		g.G[end-1].indegree++;  //指向某个顶点一次,对应的入度加1
	}
	return g;
}

void  OutputGraph(Graph g)
{
	for (int i=0; i < g.numVertexes; i++)  
    {
		cout<<g.G[i].name<<"->";;
        EdgeNode* head = g.G[i].link;
        if (head == NULL)
           cout<<"NULL";
        while(head != NULL)
        {
			cout<<(head->index)+1<<"->";
            head = head->next;
        }
       cout<<endl; 
    }
}

void  TopoSort(Graph g)
{
	int top=-1;
	for(int i=0;i<g.numVertexes;i++) //使用indegree域自己形成一个(链式存储)堆栈,不用新建堆栈
	{
		if(0==g.G[i].indegree)  //将入度为零的顶点压栈
		{
			g.G[i].indegree=top;
			top=i;
		}
	}

	for(int i=0;i<g.numVertexes;i++)
	{
		if(-1==top)
		{
			cout<<"有圈出现,不能进行拓扑排序";
			return;
		}
		else
		{
			int j=top;
			top=g.G[top].indegree; //栈顶向下移动一次
			cout<<g.G[j].name<<" "; //输出结果(出栈)
			EdgeNode *p=g.G[j].link;
			while(p!=NULL)  //输出一个顶点之后,删除与它相连的边
			{
				int k=p->index; 
				g.G[k].indegree--;  //将相应顶点的入度减1(即为删除边的操作)
				if(g.G[k].indegree==0) //将入度为零的顶点压栈
				{
					g.G[k].indegree=top;
					top=k;					
				}
				p=p->next;
			}
		}
	} 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值