#include<iostream>
#include<algorithm>
#include<stack>
#include<memory.h>
#define MAX 10000
#define OK 1
using namespace std;
stack<int>mystack;
int indegree[MAX];
struct node
{
int adjvex;
struct node *next;
}adj[MAX];
int Create(node adj[],int n,int m) //邻接表建表函数,n代表顶点数,m代表边数
{
int i;
node *p;
for(i=1;i<=n;i++)
{
adj[i].adjvex=i;
adj[i].next=NULL;
}
for(i=1;i<=m;i++)
{
cout<<"输入第"<<i<<"条边:";
int u,v;
cin>>u>>v;
p = new node;
p->adjvex = v;
p->next = adj[u].next;
adj[u].next = p;
}
return OK;
}
void print(int n) //n代表顶点数
{
int i;
node *p;
for(i=1;i<=n;i++)
{
p = &adj[i];
while(p!=NULL)
{
cout<<p->adjvex<<' ';
p=p->next;
}
cout<<endl;
}
}
/*拓扑排序*/
void topsort(node adj[],int n)
{
int i;
struct node *p;
memset(indegree,0,sizeof(indegree));
for(i=1;i<=n;i++)
{
p = adj[i].next;
while(p!=NULL)
{
indegree[p->adjvex]++;
p=p->next;
}
}
//入度为0的入栈
for(i=1;i<=n;i++)
{
if(indegree[i]==0)
mystack.push(i);
}
int count = 0;
while(mystack.size()!=0)
{
i = mystack.top();
mystack.pop();
cout<<i<<' '; //输出源点(入度为0)
count++;
for(p=adj[i].next;p!=NULL;p=p->next)
{
int k = p->adjvex;
indegree[k]--; //对应的入度数量要减 1
if(indegree[k]==0) //入度为0则入栈
mystack.push(k);
}
}
cout<<endl;
/*如果入度为源点栈为空,但图还有剩余元素则判断有环(count记录输出的顶点数量不等于图的顶点数)*/
if(count<n){
cout<<"有回路"<<endl;
}
}
int main()
{
int n;
int m;
cout<<"请输入顶点数及边数:";
cin>>n>>m;
Create(adj,n,m);
cout<<"输入的邻接表为:"<<endl;
print(n);
cout<<"拓扑排序结果为:"<<endl;
topsort(adj,n);
return 0;
}
//对应顶点输入的情况
/*拓扑排序:入度为0的输出,由它指向的相关的边删除,在此基础上讨论其他顶点的入度情况*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_VERTEX_NUM 20
#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define FALSE 0
#include<stack>
#define MAX 10000
using namespace std;
typedef int Status ;
typedef char VertexType;
typedef int QElemType;
typedef struct ArcNode
{
int adjvex; //邻接点域,存储该邻点顶点对应的下标
struct ArcNode *nextarc; //邻节点
int weight; //权值
}ArcNode;
/*邻接表结构*/
typedef struct VNode
{
VertexType data; //顶点对应的值
ArcNode *firstarc; //边表头指针指向邻顶点
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum,arcnum; //顶点数,边数
}ALGraph;
void CreateALGraph(ALGraph *G) //构建图
{
ArcNode *p;
int i,j,k;
printf("输入顶点与边的数目:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
getchar();
printf("输入顶点值:\n");
for(i=1;i<=G->vexnum;i++)
{
//printf("input %dth vex(char) :\n");
scanf("%c",&G->vertices[i].data);
getchar();
G->vertices[i].firstarc=NULL;
}
//建立边表
printf("输入邻接表对应的下标:\n");
for(k=1;k<=G->arcnum;k++)
{
scanf("%d%d",&i,&j); //边对应的两个顶点下标并将俩顶点联系起来
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p;
}
}
/*记录各顶点的入度情况*/
void FindIndgree(ALGraph G,int Indegree[MAX]){
memset(Indegree,0,sizeof(Indegree));
ArcNode *p;
for(int i = 1;i<=G.vexnum;i++){
p = G.vertices[i].firstarc;
while(p)
{
Indegree[p->adjvex]++;
p = p->nextarc;
}
}
}
void Topological_Sort(ALGraph G){
stack<int> s;
ArcNode *p;
int count = 0;
int Indegree[MAX];
FindIndgree(G,Indegree);
/*入度为0的入栈*/
for(int i = 1;i<=G.vexnum;i++){
if(!Indegree[i]){
s.push(i);
}
}
while(!s.empty()){
int item = s.top();
printf("%c ",G.vertices[item].data);
s.pop();
count++;
for(p=G.vertices[item].firstarc;p;p=p->nextarc){
int k = p->adjvex;
if(!(--Indegree[k])) s.push(k); /*(--Indegree[k])是指原来指向它的那个指向边撤去,如果此时该顶点对应的入度为0,则入栈*/
}
}
if(count<G.vexnum){
printf("有回路:\n");
}
}
int main(){
ALGraph G;
CreateALGraph(&G);
printf("拓扑排序为:\n");
Topological_Sort(G);
return 0;
}
拓扑排序
最新推荐文章于 2018-11-20 15:49:02 发布
659

被折叠的 条评论
为什么被折叠?



