对于有向无环图G=(V,E)进行拓扑排序后,结果为该图所有顶点的线性序列,如果G包含边(u,v),那么在排序后的序列中,u就一定出现在v的前面。
所有,一个图的拓扑排序可以看成是图中所有顶点沿着水平线排列而成的一个序列,使得所有有向边均从左指向右。
DAG的拓扑排序主要依赖dfs来实现:
/*
file:topligic_sort.c
brief:使用dfs对有向无环图进行拓扑排序,先用dfs计算出所有顶点的finish time,
每个顶点结束之后,将它插入一个链表的前面
version;1.0 yejing@2014.09.01
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NO_WEIGHT 0x7fffffff
#define INFINITY 0x7fffffff
int time = 0;//时间戳
typedef enum{
WHITE,
GRAY,
BLACK
}color_t;
typedef struct __graph{
char* vex_vector;//顶点向量
int* color;//颜色
int* parent;//父节点
int* deepth;//节点被发现时的深度,bfs使用
int* disc_tm;//节点被发现的时间
int* fini_tm;//节点被搜索完成的时间
int arcs[255][255];
int vexnum, arcnum;
}graph_t;
typedef struct __list{
int vex_index;
struct __list next;
}list_t;
list_t* list = NULL;
list_t* creat_list(int value){
list_t* list_head = (list_t*)malloc(sizeof(list_t));
if(!list_head){
printf("malloc error errno:%d \n", errno);
return NULL;
}
list_head->vex_index = value;
return list_head;
}
list_t* add_head_to_list(list_t* list_head, int value){
if(!list_head)
return;
list_t* tmp = list_head;
list_head = (list_t*)malloc(sizeof(list_t));
if(!list_head)
return tmp;
list_head->vex_index = value;
list_head->next = tmp;
return list_head;
}
int find(graph_t g, char vex_vector){
int i = 0;
for(i; i < g.vexnum; ++i)
if(g.vex_vector[i] == vex_vector)
return i;
return -1;
}
graph_t create_graph(void){
int i = 0, j = 0;
graph_t graph;
memset((char*)&graph, 0, sizeof(graph));
printf("input the arcnum, less than 255\n");
scanf("%d", &graph.arcnum);
getchar();
printf("input the vexnum, less than 255\n");
scanf("%d", &graph.vexnum);
getchar();
graph.color = (int*)malloc(sizeof(int) * graph.vexnum);
graph.deepth = (int*)malloc(sizeof(int) * graph.vexnum);
graph.parent = (int*)malloc(sizeof(int) * graph.vexnum);
graph.disc_tm = (int*)malloc(sizeof(int) * graph.vexnum);
graph.fini_tm = (int*)malloc(sizeof(int) * graph.vexnum);
for(i = 0; i < graph.vexnum; ++i){
graph.color[i] = WHITE;
graph.deepth[i] = INFINITY;
graph.parent[i] = -1;
graph.disc_tm[i] = 0;
graph.fini_tm[i] = 0;
}
printf("begin inputing the vex_vector, total num:%d \n", graph.vexnum);
graph.vex_vector = (char*)malloc(sizeof(char) * graph.vexnum);
for(i = 0; i < graph.vexnum; ++i){
printf("vex_vector %d \n", i);
scanf("%c", &graph.vex_vector[i]);
getchar();
}
printf("vex_vector input finished\n");
printf("initializing arc weights...\n");
for(i = 0; i < graph.vexnum; ++i)
for(j = 0; j < graph.vexnum; ++j)
graph.arcs[i][j] = NO_WEIGHT;
int arc_weight;
int tmp_index1, tmp_index2;
char vex_vector1, vex_vector2;
printf("begin inputing the weight of the arc, total num:%d format: vex_vector1 vex_vector2 arc_weight\n", graph.arcnum);
for(i = 0; i < graph.arcnum; ++i){
printf("arc %d\n", i);
scanf("%c %c %d", &vex_vector1, &vex_vector2, &arc_weight);
getchar();
tmp_index1 = find(graph, vex_vector1);
tmp_index2 = find(graph, vex_vector2);
if(tmp_index2 && tmp_index1)
graph.arcs[tmp_index1][tmp_index2] = arc_weight;//有向图,单向边有权
else
printf("input vex_vectors error, vex_vectors are %c and %c\n", vex_vector1, vex_vector2);
}
printf("weight input finished\n");
return graph;
}
int first_vex_of_graph(graph_t graph, int k)
{
int i;
if(k>=0 && k<graph.vexnum)
for(i=0;i<graph.vexnum;i++)
if(graph.arcs[k][i] != NO_WEIGHT)
return i;
return -1;
}
int next_vex_of_graph(graph_t graph, int i, int j)
{
int k;
if(i>=0 && i<graph.vexnum && j>=0 && j<graph.vexnum)
for(k=j+1; k<graph.vexnum; k++)
if(graph.arcs[i][k] != NO_WEIGHT)
return k;
return -1;
}
void dfs_visit(graph_t* pgraph, int u){
int i = 0;
pgraph->color[u] = GRAY;
pgraph->disc_tm[u] = ++time;
for(i = first_vex_of_graph(*pgraph, u); i >= 0; i = next_vex_of_graph(*pgraph, u, i)){
if(pgraph->color[i] == WHITE){
pgraph->parent[i] = u;
dfs_visit(pgraph, i);
}
}
pgraph->color[u] = BLACK;
pgraph->fini_tm[u] = ++time;
if(!list)
list = creat_list(u);
else
list = add_head_to_list(list, u);
return;
}
void deepth_first_search(graph_t graph)
{
int i = 0;
for(i = 0; i < graph.vexnum; ++i){
if(graph.color[i] == WHITE)
dfs_visit(&graph, i);
}
return;
}
void show_result(graph_t graph){
if(!list){
printf("damn, there is no list,0.0 \n");
return;
}
printf("result is: ")
while(list){
printf("%c ", graph.vex_vector[list->vex_index]);
}
printf("\n");
}
int main(int argc, char* argv[]){
graph_t graph = create_graph();
deepth_first_search(graph);
show_result(graph);
return 1;
}