拓扑排序之变量序列代码(一)

2014-11-23 17:40:23 · 作者: · 浏览: 18
/*
Name:
Copyright:
Author:
Date: 17-11-14 21:02
Description: 拓扑排序之变量序列
假设有n个变量(1<=n<=26,变量名用单个小写字母表示),还有m个二元组(u,v),分别表示变量u小于v。那么,所有变量从小到大排列起来应该是什么样子的呢?
例如有4个变量a,b,c,d,若以知a Input
输入为一个字符串data,其中包含N+N个字符,表示N个关系式(1<=N<=100000),例如序列"abcbdc"表示a Output
给出一个字符串,其中存储了一个符合要求的变量序列,例如,字符串"adcb"表示a
*/
#include
#include


#define true 1
#define false 0
#define MAXM 26 //最大变量(顶点)数量
#define MAXN 100000 //最大关系式数量


typedef char VertexType; //顶点类型由用户自定义
typedef int EdgeType; //边上的权值类型由用户自定义


typedef struct EdgeNode{ //边表结点
int adjvex; //邻接点域,存储该顶点对应的下标
// EdgeType weight; //权值,对于非网图可以不需要
struct EdgeNode *next; //链域,指向下一个邻接点
} EdgeNode;


typedef struct VertexNode{ //顶点表结点
VertexType data; //顶点域,存储顶点信息
int in; //存储顶点入度的数量
EdgeNode *firstEdge; //边表头指针
} VertexNode;


typedef struct Edge{ //边集数组
int u, v; //弧尾和弧头
int next; //指向同一个弧尾的下一条边
// EdgeType weight; //权值,对于非网图可以不需要
} EdgeLib;


int book[MAXM] = {0}; //标记某字母是否出现


int IsTopoSeq(char *data, char *topo);//根据关系列表data,判断topo字符串是否为拓扑序列
int CreateGraph(char *data, VertexNode *GL);//创建一个图
void PrintGraph(VertexNode *GL);//输出图
int TopoLogicalSort_DFS(char *topo, VertexNode *GL, int n);//拓扑排序,获取拓扑序列,若存在环则返回假
int TopoLogicalSort_BFS(char *topo, VertexNode *GL, int n);//拓扑排序,获取拓扑序列,若存在环则返回假
int CreateGraph_2(char *data, int In[], int first[], EdgeLib edge[]);//创建一个图
void PrintGraph_2(int first[], EdgeLib edge[]);//输出图
int TopoLogicalSort(char *topo, EdgeLib edge[], int In[], int first[], int n);//拓扑排序,获取拓扑序列,若存在环则返回假,使用队列存储拓扑序列


int main()
{
int i, n;
VertexNode GL[MAXM];
char topo[MAXM+1];
char data[MAXN+MAXN+1];
int In[MAXM], first[MAXM]; //存储顶点信息
EdgeLib edge[MAXN]; //存储边信息


gets(data);
n = CreateGraph_2(data, In, first, edge);//创建一个图
PrintGraph_2(first, edge);//输出图

if (TopoLogicalSort(topo, edge, In, first, n))//采用拓扑排序构造拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");

if (IsTopoSeq(data, topo))//根据关系列表data,判断topo字符串是否为拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");

gets(data);
n = CreateGraph(data, GL);//创建一个图
PrintGraph(GL);//输出图
if (IsTopoSeq(data, topo))//根据关系列表data,判断topo字符串是否为拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");

if (TopoLogicalSort_BFS(topo, GL, n))//采用拓扑排序构造拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");

gets(data);
n = CreateGraph(data, GL);//创建一个图
PrintGraph(GL);//输出图

if (TopoLogicalSort_DFS(topo, GL, n))//采用拓扑排序构造拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");

if (IsTopoSeq(data, topo))//根据关系列表data,判断topo字符串是否为拓扑序列
puts(topo);
else
puts("不存在满足条件的序列");




return 0;
}
/*
函数名称:CreateGraph
函数功能:把顶点和边信息读入到表示图的邻接表中
输入变量:char *data:存储了N个关系式的字符串
VertexNode *GL : 顶点表数组
输出变量:表示图的顶点表数组
返回值:int :顶点数量
*/
int CreateGraph(char *data, VertexNode *GL)
{
int i, u, v;
int count = 0;//记录顶点数量
EdgeNode *e;

for (i=0; i {
GL[i].data = i + 'a';
GL[i].in = 0;
GL[i].firstEdge = NULL;
book[i] = 0;
}

for (i=0; data[i]!='\0'; i+=2)//每次读取两个变量
{
u = data[i] - 'a'; //字母转换为数字,'a'对应0,'b'对应1,以此类推
v = data[i+1] - 'a';
book[u] = book[v] = 1;

e = (EdgeNode*)malloc(sizeof(EdgeNode)); //采用头插法插入边表结点
if (!e)
{
puts("Error");
exit(1);
}
e->adjvex = v;
e->next = GL[u].firstEdge;
GL[u].firstEdge = e;

GL[v].in++;
}

for (i=0; i {
if (book[i] != 0)
count++;
}

return count;
}


void PrintGraph(VertexNode *GL)//输出图
{
int u, v;
EdgeNode *e;

for (u=0; u {
printf("G[%d] = %c: ", u, GL[u].data);
for (e=GL[u].firstEdge; e!=NULL; e=e->next)//将u的邻接点入度减1,并将入度为0的顶点入栈
{