注意的问题:
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;
}
}
}
}