【发布时间】:2021-04-20 06:22:27
【问题描述】:
我正在尝试在 C 中实现 Knuth 的拓扑排序算法。当我搜索在线资源时,我看到的都是 Kahn 算法的实现,这让我很困惑。他们都一样吗?还是他们不同?这是基于我研究的实现。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1000
void create_graph();
void add(int vertex);
int del();
int isEmpty();
int find_indegree_of_vertex(int vertex);
int total_vertices;
int adjacent_matrix[MAX][MAX];
int queue[MAX];
int front = -1;
int rear = -1;
int main()
{
int i, vertex, count, topological_sort[MAX], indegree[MAX];
create_graph();
for(i = 1; i <= total_vertices; i++)
{
indegree[i] = find_indegree_of_vertex(i);
if(indegree[i] == 0)
{
add(i);
}
}
count = 0;
while(!isEmpty() && count < total_vertices)
{
vertex = del();
topological_sort[++count] = vertex;
for(i = 1; i <= total_vertices; i++)
{
if(adjacent_matrix[vertex][i] == 1)
{
adjacent_matrix[vertex][i] = 0;
indegree[i] = indegree[i] - 1;
if(indegree[i] == 0)
{
add(i);
}
}
}
}
for(i = 1; i <= count; i++)
{
printf("%d ", topological_sort[i]);
}
printf("\n");
return 0;
}
void add(int vertex)
{
if(!(rear == MAX - 1))
{
if(front == -1)
{
front = 0;
}
rear = rear + 1;
queue[rear] = vertex ;
}
}
int isEmpty()
{
if(front == -1 || front > rear)
{
return 1;
}
else
{
return 0;
}
}
int del()
{
int element;
if(front == -1 || front > rear)
{
exit(1);
}
else
{
element = queue[front];
front = front + 1;
return element;
}
}
int find_indegree_of_vertex(int vertex)
{
int count, total_indegree = 0;
for(count = 0; count < total_vertices; count++)
{
if(adjacent_matrix[count][vertex] == 1)
{
total_indegree++;
}
}
return total_indegree;
}
void create_graph()
{
int count, maximum_edges, origin_vertex, destination_vertex;
char v1[1000], v2[1000];
char temp[10];
scanf("%d\n", &total_vertices);
maximum_edges = total_vertices * (total_vertices - 1);
for(count = 1; count <= maximum_edges; count++)
{
fgets(temp, sizeof(temp), stdin);;
char * splitter;
splitter = strtok(temp, " ");
strncpy(v1, splitter, strlen(splitter)+1);
splitter = strtok(NULL, " ");
strncpy(v2, splitter, strlen(splitter)+1);
origin_vertex = atoi(v1);
destination_vertex = atoi(v2);
if((origin_vertex == 0) && (destination_vertex == 0))
{
break;
}
else
adjacent_matrix[origin_vertex][destination_vertex] = 1;
}
}
示例输入:
15 (Number of vertices)
1 2
2 3
4 5
5 1
5 12
5 6
7 6
8 9
10 11
12 10
12 13
13 14
13 9
14 15
0 0 (End of entries, not a part of the adjacency matrix.)
输出:
4 7 8 5 1 6 12 2 10 13 3 11 9 14 15
预期输出(来自我们的课堂活动):
4 7 8 5 6 12 1 13 10 2 9 14 11 3 15 (Notice the difference!)
我的代码接受对的输入,并在应用拓扑排序后返回顺序。为简单起见,我假设该条目是拓扑排序的有效图。
【问题讨论】:
-
嗯...对我来说,不清楚你在问什么。代码有问题吗?
-
对不起。我的问题是,Kahn 的算法与 Knuth 的算法不同吗?如果是这样,Knuth 的算法究竟是如何实现的?我有自己的实现,但这是基于卡恩的。
-
你从哪里得到 Knuth 算法的规范?淘宝?别的地方?你在哪里找过卡恩的算法?
-
对于卡恩算法,我从 geeksforgeeks.org/topological-sorting-indegree-based-solution/ 和 codezclub.com/c-topological-sorting-algorithm-example/ 获得了它,我对遵循我的意见。对于 Knuth,我还没有看到,但是有 Knuth 的 Toposort 的文章。
-
好吧,如果你真的读过 TAOCP(计算机编程的艺术,第 1 卷,第 3 版中的第 2.2.3 节),你会发现 Knuth 的“算法 T(拓扑排序)”以及评论:一种类似于算法 T 的拓扑排序技术(但没有队列链接的重要特征)由 A. B. Kahn, CACM 5 (1962), 558-562 首次发表。。这表明 Knuth 的算法 T 与 Kahn 的算法不同。如果您还没有自己的 TAOCP 副本,那么现在可能是进行投资的好时机。做不到这一点,是时候突袭图书馆了。
标签: c sorting graph directed-acyclic-graphs knuth