有向图的拓扑有向序列
2005-12-20 12:37
288 查看
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include<conio.h>
#include<iostream>
#define MAX_VERTEX_NUM 20 /*最大顶点数*/
#define INFINITY 32767 /*最大值*/
#define STACK_INIT_SIZE 100 //栈的最大空间
#define STACKINCREMENT 20 //栈的追加空间单位
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define OUTPLACE -1
typedef int Status;
typedef int VertexType;
typedef int InfoType;
typedef int SElemType;
typedef struct{
SElemType *base; /*栈底指针*/
SElemType *top; /*栈顶指针*/
int stacksize; /*栈的大小*/
}SqStack;
typedef struct ArcNode{
int adjvex; /*该弧所指向的顶点的位置*/
struct ArcNode *nextarc; /*指向一下条弧的指针*/
InfoType info; /*该弧相关信息*/
}ArcNode;
typedef struct VNode{
VertexType data; /*顶点信息*/
ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum; /*图当前的顶点数和弧数*/
int kind; /*图的种类标志*/
}ALGraph;
int indegree[MAX_VERTEX_NUM];
Status InitStack(SqStack &S) //初始化栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status GetTop(SqStack &S,SElemType &e) //取栈顶元素
{
if(S.top==S.base) return ERROR;
e=*(S.top-1);
return OK;
}
Status Push(SqStack &S,SElemType e1) //进栈操作
{
if(S.top-S.base>=S.stacksize){
S.base=(SElemType *)realloc(S.base,
(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e1;
return OK;
}
Status Pop(SqStack &S,SElemType &e) //出栈操作
{
if(S.top==S.base) return ERROR;
e=*(--S.top);
return OK;
}
Status StackEmpty(SqStack S) //判空操作
{
if(S.top==S.base)
return 1;
else
return 0;
}
int LocateVex(ALGraph &G,VertexType v) /*返回顶点v在G中下标*/
{
int i;
for(i=0;i<G.vexnum;i++)
if(v==G.vertices[i].data) return i;
return -1;
}
ALGraph Build_ALG_DN() /*创建一个有向网*/
{ ALGraph G;
int i,j,k,v1,v2;
ArcNode *p=NULL,*q=NULL;
for(i=0;i<MAX_VERTEX_NUM;i++)
G.vertices[i].firstarc=NULL; /*初始化*/
printf("请输入顶点数:");
scanf("%d",&G.vexnum); /*输入顶点数*/
if(G.vexnum<0)
{
printf("错误/n");
return G;
}
printf("请输入边数:");
scanf("%d",&G.arcnum); /*输入边数*/
if(G.arcnum<0)
{
printf("错误/n");
return G;
}
for(i=0;i<G.vexnum;i++) /*输入顶点序列*/
{
printf("请输入顶点信息: ");
scanf("%d",&G.vertices[i].data);
}
for(i=0;i<G.arcnum;i++) /*输入边的信息*/
{
printf("请输入边的信息(v1,v2):");
scanf("%d,%d,%d",&v1,&v2);
j=LocateVex(G,v1),k=LocateVex(G,v2); /*获取v1和v2在G中的位置*/
if(j<0||k<0||j==k)
{
printf("ERROR!!/n");
i--;continue;
} /* 如果顶点输入错误,继续 */
p=(ArcNode *)malloc(sizeof(ArcNode)); /*分配结点*/
p->adjvex=k; p->nextarc=NULL;
if(!G.vertices[j].firstarc) G.vertices[j].firstarc=p; /*p是v1的第一条弧*/
else {
for(q=G.vertices[j].firstarc;q->nextarc;q=q->nextarc); /*找到链表的最后一个结点*/
q->nextarc=p;
}
}
return G;
}
Status Insert_Vertex_ALGraph(ALGraph &G) /*插入一个顶点*/
{
char a;
char c;
c='y';
while(c=='y')
{
printf("请输入顶点信息:");
scanf("%d",&a);
G.vertices[G.vexnum++].data=a; /*插入顶点,顶点数加1*/
printf("你还要插入顶点吗?(y/n)?");
scanf("%s",&c);
}
return OK;
}
Status Insert_Arc_ALGraph(ALGraph &G) /*插入一条边*/
{
int j,k;
char v1,v2,c;
ArcNode *p,*q;
c='y';
while(c=='y') /*判断是否插入边*/
{
printf("请输入边的信息(v1,v2):");
scanf("%d,%d,%d",&v1,&v2); /*输入边的信息(顶点)*/
j=LocateVex(G,v1); k=LocateVex(G,v2);
if(j<0||k<0||j==k){printf("ERROR!!/n"); continue;} /*如果顶点不属于G,继续*/
p=(ArcNode *)malloc(sizeof(ArcNode)); /*分配一个结点*/
p->adjvex=k; p->nextarc=NULL;
if(!G.vertices[j].firstarc) G.vertices[j].firstarc=p; /*如果v1没有边,插入为第一条边*/
else /*如果v1有边,将新边插到最后一个结点后*/
{
for(q=G.vertices[j].firstarc;q->nextarc;q=q->nextarc);
q->nextarc=p;
}
G.arcnum++;
printf("你还要插入边吗?(y/n)");
scanf("%s",&c);
}
return OK;
}
Status FindInDegree(ALGraph G,int indegree[]) //对有向图的各个顶点求入度
{
int i,k;
ArcNode *p;
for(i=0;i<G.vexnum;i++)
{
if(G.vertices[i].firstarc)
{
p=G.vertices[i].firstarc;
k=p->adjvex;
indegree[k]=1;
while(p->nextarc)
{
p=p->nextarc;
k=p->adjvex;
++indegree[k];
}//while
}//if
}//for
return OK;
}
Status TopologicalSort(ALGraph &G)
{ //输出有向图无环图的拓扑有向序列,若有回路,返回错误。
int i,count,k;
ArcNode *p;
SqStack S;
FindInDegree(G,indegree); //对各顶点求入度
InitStack(S);
for(i=0;i<G.vexnum;i++)
if(!indegree[i]) Push(S,i); //0入度顶点进栈
count=0;
while(!
4000
StackEmpty(S)) //栈非空
{
Pop(S,i);
printf(" %d ",G.vertices[i].data);
count++; //输出i号顶点,计数加一
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!(--indegree[k])) Push(S,k); //i号顶点的每一个邻接点入度减一,若减后为零,入栈
}//for
}//while
if(count<G.vexnum) return ERROR; //如果输出的顶点数小于图的顶点数,则有向图内有环,返回错误
else return OK;
}
int main()
{
int i;
int c=1;
ALGraph G;
ArcNode *p;
printf("本程序将建立一个用邻接表方式存储的有向图,可以进行插入顶点或边的操作,/n可以输出有向图的信息或输出该有向图的拓扑有向序列。/n请按任意键继续/n");
getch();
system("cls");
printf("1.创建有向图:(第一次请先执行这一步!)/n");
system("cls");
printf("========创建有向图==========/n");
printf("所有的输入都为整数,边的输入方式为输入该边由哪个顶点指向哪个顶点,/n两个顶点用“,”隔开。/n");
G=Build_ALG_DN();
printf("请按任意键继续选择操作。/n");
getch();
while(c!=0)
{
system("cls");
printf("1.插入顶点/n");
printf("2.插入边/n");
printf("3.输出有向图的信息(顶点和边)/n");
printf("4.输出有向图的拓扑有向序列/n");
printf("0.退出/n");
printf("请选择你要进行的操作:");
scanf("%d",&c);
switch(c)
{
case 1:
system("cls");
printf("========插入顶点===========/n");
Insert_Vertex_ALGraph(G); /*插入顶点*/
printf("请按任意键继续选择操作。/n");
getch();
break;
case 2:
system("cls");
printf("========插入边==========/n");
Insert_Arc_ALGraph(G); //插入边
printf("请按任意键继续选择操作。/n");
getch();
break;
case 3:
system("cls");
printf("========输出有向图=========/n");
for(i=0;i<G.vexnum;i++) //输出顶点的信息
{
printf("%d ",G.vertices[i].data);
}
printf("/n");
for(i=0;i<G.vexnum;i++) //输出边的信息
{
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
printf("%d-->%d ",G.vertices[i].data,G.vertices[p->adjvex].data);
}
printf("/n");
printf("/n请按任意键继续选择操作。/n");
getch();
break;
case 4:
system("cls");
printf("========输出有向图的拓扑有向序列===========/n");
if(!TopologicalSort(G))
printf("/n有向图中有回路,错误/n");
printf("/n请按任意键继续选择操作。/n");
getch();
break;
case 0:
break;
default:
printf("/n你的选择是错误的!/n");
getch();
break;
}//switch
}//while
printf("/n欢迎下次再来……^_^/n");
getch();
return 0;
}
我是大三的计算机方面专业的学生,
请大家指点……
#include <string.h>
#include <malloc.h>
#include<conio.h>
#include<iostream>
#define MAX_VERTEX_NUM 20 /*最大顶点数*/
#define INFINITY 32767 /*最大值*/
#define STACK_INIT_SIZE 100 //栈的最大空间
#define STACKINCREMENT 20 //栈的追加空间单位
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define OUTPLACE -1
typedef int Status;
typedef int VertexType;
typedef int InfoType;
typedef int SElemType;
typedef struct{
SElemType *base; /*栈底指针*/
SElemType *top; /*栈顶指针*/
int stacksize; /*栈的大小*/
}SqStack;
typedef struct ArcNode{
int adjvex; /*该弧所指向的顶点的位置*/
struct ArcNode *nextarc; /*指向一下条弧的指针*/
InfoType info; /*该弧相关信息*/
}ArcNode;
typedef struct VNode{
VertexType data; /*顶点信息*/
ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum; /*图当前的顶点数和弧数*/
int kind; /*图的种类标志*/
}ALGraph;
int indegree[MAX_VERTEX_NUM];
Status InitStack(SqStack &S) //初始化栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status GetTop(SqStack &S,SElemType &e) //取栈顶元素
{
if(S.top==S.base) return ERROR;
e=*(S.top-1);
return OK;
}
Status Push(SqStack &S,SElemType e1) //进栈操作
{
if(S.top-S.base>=S.stacksize){
S.base=(SElemType *)realloc(S.base,
(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e1;
return OK;
}
Status Pop(SqStack &S,SElemType &e) //出栈操作
{
if(S.top==S.base) return ERROR;
e=*(--S.top);
return OK;
}
Status StackEmpty(SqStack S) //判空操作
{
if(S.top==S.base)
return 1;
else
return 0;
}
int LocateVex(ALGraph &G,VertexType v) /*返回顶点v在G中下标*/
{
int i;
for(i=0;i<G.vexnum;i++)
if(v==G.vertices[i].data) return i;
return -1;
}
ALGraph Build_ALG_DN() /*创建一个有向网*/
{ ALGraph G;
int i,j,k,v1,v2;
ArcNode *p=NULL,*q=NULL;
for(i=0;i<MAX_VERTEX_NUM;i++)
G.vertices[i].firstarc=NULL; /*初始化*/
printf("请输入顶点数:");
scanf("%d",&G.vexnum); /*输入顶点数*/
if(G.vexnum<0)
{
printf("错误/n");
return G;
}
printf("请输入边数:");
scanf("%d",&G.arcnum); /*输入边数*/
if(G.arcnum<0)
{
printf("错误/n");
return G;
}
for(i=0;i<G.vexnum;i++) /*输入顶点序列*/
{
printf("请输入顶点信息: ");
scanf("%d",&G.vertices[i].data);
}
for(i=0;i<G.arcnum;i++) /*输入边的信息*/
{
printf("请输入边的信息(v1,v2):");
scanf("%d,%d,%d",&v1,&v2);
j=LocateVex(G,v1),k=LocateVex(G,v2); /*获取v1和v2在G中的位置*/
if(j<0||k<0||j==k)
{
printf("ERROR!!/n");
i--;continue;
} /* 如果顶点输入错误,继续 */
p=(ArcNode *)malloc(sizeof(ArcNode)); /*分配结点*/
p->adjvex=k; p->nextarc=NULL;
if(!G.vertices[j].firstarc) G.vertices[j].firstarc=p; /*p是v1的第一条弧*/
else {
for(q=G.vertices[j].firstarc;q->nextarc;q=q->nextarc); /*找到链表的最后一个结点*/
q->nextarc=p;
}
}
return G;
}
Status Insert_Vertex_ALGraph(ALGraph &G) /*插入一个顶点*/
{
char a;
char c;
c='y';
while(c=='y')
{
printf("请输入顶点信息:");
scanf("%d",&a);
G.vertices[G.vexnum++].data=a; /*插入顶点,顶点数加1*/
printf("你还要插入顶点吗?(y/n)?");
scanf("%s",&c);
}
return OK;
}
Status Insert_Arc_ALGraph(ALGraph &G) /*插入一条边*/
{
int j,k;
char v1,v2,c;
ArcNode *p,*q;
c='y';
while(c=='y') /*判断是否插入边*/
{
printf("请输入边的信息(v1,v2):");
scanf("%d,%d,%d",&v1,&v2); /*输入边的信息(顶点)*/
j=LocateVex(G,v1); k=LocateVex(G,v2);
if(j<0||k<0||j==k){printf("ERROR!!/n"); continue;} /*如果顶点不属于G,继续*/
p=(ArcNode *)malloc(sizeof(ArcNode)); /*分配一个结点*/
p->adjvex=k; p->nextarc=NULL;
if(!G.vertices[j].firstarc) G.vertices[j].firstarc=p; /*如果v1没有边,插入为第一条边*/
else /*如果v1有边,将新边插到最后一个结点后*/
{
for(q=G.vertices[j].firstarc;q->nextarc;q=q->nextarc);
q->nextarc=p;
}
G.arcnum++;
printf("你还要插入边吗?(y/n)");
scanf("%s",&c);
}
return OK;
}
Status FindInDegree(ALGraph G,int indegree[]) //对有向图的各个顶点求入度
{
int i,k;
ArcNode *p;
for(i=0;i<G.vexnum;i++)
{
if(G.vertices[i].firstarc)
{
p=G.vertices[i].firstarc;
k=p->adjvex;
indegree[k]=1;
while(p->nextarc)
{
p=p->nextarc;
k=p->adjvex;
++indegree[k];
}//while
}//if
}//for
return OK;
}
Status TopologicalSort(ALGraph &G)
{ //输出有向图无环图的拓扑有向序列,若有回路,返回错误。
int i,count,k;
ArcNode *p;
SqStack S;
FindInDegree(G,indegree); //对各顶点求入度
InitStack(S);
for(i=0;i<G.vexnum;i++)
if(!indegree[i]) Push(S,i); //0入度顶点进栈
count=0;
while(!
4000
StackEmpty(S)) //栈非空
{
Pop(S,i);
printf(" %d ",G.vertices[i].data);
count++; //输出i号顶点,计数加一
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!(--indegree[k])) Push(S,k); //i号顶点的每一个邻接点入度减一,若减后为零,入栈
}//for
}//while
if(count<G.vexnum) return ERROR; //如果输出的顶点数小于图的顶点数,则有向图内有环,返回错误
else return OK;
}
int main()
{
int i;
int c=1;
ALGraph G;
ArcNode *p;
printf("本程序将建立一个用邻接表方式存储的有向图,可以进行插入顶点或边的操作,/n可以输出有向图的信息或输出该有向图的拓扑有向序列。/n请按任意键继续/n");
getch();
system("cls");
printf("1.创建有向图:(第一次请先执行这一步!)/n");
system("cls");
printf("========创建有向图==========/n");
printf("所有的输入都为整数,边的输入方式为输入该边由哪个顶点指向哪个顶点,/n两个顶点用“,”隔开。/n");
G=Build_ALG_DN();
printf("请按任意键继续选择操作。/n");
getch();
while(c!=0)
{
system("cls");
printf("1.插入顶点/n");
printf("2.插入边/n");
printf("3.输出有向图的信息(顶点和边)/n");
printf("4.输出有向图的拓扑有向序列/n");
printf("0.退出/n");
printf("请选择你要进行的操作:");
scanf("%d",&c);
switch(c)
{
case 1:
system("cls");
printf("========插入顶点===========/n");
Insert_Vertex_ALGraph(G); /*插入顶点*/
printf("请按任意键继续选择操作。/n");
getch();
break;
case 2:
system("cls");
printf("========插入边==========/n");
Insert_Arc_ALGraph(G); //插入边
printf("请按任意键继续选择操作。/n");
getch();
break;
case 3:
system("cls");
printf("========输出有向图=========/n");
for(i=0;i<G.vexnum;i++) //输出顶点的信息
{
printf("%d ",G.vertices[i].data);
}
printf("/n");
for(i=0;i<G.vexnum;i++) //输出边的信息
{
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
printf("%d-->%d ",G.vertices[i].data,G.vertices[p->adjvex].data);
}
printf("/n");
printf("/n请按任意键继续选择操作。/n");
getch();
break;
case 4:
system("cls");
printf("========输出有向图的拓扑有向序列===========/n");
if(!TopologicalSort(G))
printf("/n有向图中有回路,错误/n");
printf("/n请按任意键继续选择操作。/n");
getch();
break;
case 0:
break;
default:
printf("/n你的选择是错误的!/n");
getch();
break;
}//switch
}//while
printf("/n欢迎下次再来……^_^/n");
getch();
return 0;
}
我是大三的计算机方面专业的学生,
请大家指点……
相关文章推荐
- 图结构练习——判断给定图是否存在合法拓扑序列(topo)
- 图结构练习——判断给定图是否存在合法拓扑序列
- 图结构练习——判断给定图是否存在合法拓扑序列
- 图结构练习——判断给定图是否存在合法拓扑序列
- poj 3687 Labeling Balls 【拓扑排序 输出元素在拓扑序列中的位置】
- 设计算法,输出有向无环图G的拓扑序列。图采用邻接表存储。
- 深度优先DFS和广度优先BFS,破圈法,拓扑序列,prim,克鲁斯卡尔等生成算法(需要用到并查集)迪杰斯特拉算法和弗洛伊德的总结
- 图结构练习——判断给定图是否存在合法拓扑序列
- 7-10 任务调度的合理性(25 分)(拓扑序列判断是否存在环)
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 2140 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 2140-数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列---bfs判断又向图的无环问题
- 拓扑序列的实现
- OJ2140图结构练习——判断给定图是否存在合法拓扑序列
- 图结构练习——判断给定图是否存在合法拓扑序列
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
- 拓扑序列
- 【模板】拓扑序列 (模版题:XJOI P1064)