【发布时间】:2014-05-20 04:45:25
【问题描述】:
好的,我必须对图进行拓扑排序算法。我需要找到度数为 0 的节点并将其排队,然后打印它并删除所有通往它的边缘。我通过减少 countList 映射中进入边缘的数量来移除边缘。我将邻接列表作为地图,并将每个节点的度数作为地图。我的算法只访问邻接列表的第一个元素。所以我的输出队列只显示邻接列表映射的第一个键。一遍又一遍。我在 25 处停止了 while 循环,所以它不会是无限的。
string z = "";
string a = "";
cout << "Queue: ";
do{
for(it = countList.begin(); it!=countList.end(); ++it){
if(it->second == 0){
Q.push(it->first);
countList.at(it->first)--;
z = adjList[it->first];
cout <<"z: " << z <<endl;
//remove edges
for(int i = 0; i< z.length(); i++){
a = z.at(i);
cout << "z at " <<i << " : " <<a <<endl;
countList.at(a)--;
}//end for
}//end if
//cout << Q.front() << ", ";
//Q.pop();
}//end for
cout << Q.front() << ", ";
Q.pop();
}while(!Q.empty());
有人可以帮助我理解为什么它没有遍历 countList 并且只停留在第一个元素上吗?
谢谢。
所以我将 countList.at(a)-+1 更改为 countList.at(a)-- 以进行适当的递减。 现在输出不仅仅是度数为 0 的第一个顶点。但是输出仍然是错误的。
这就是全部。 我的变量声明
vector<string> E;
map<string, string> adjList;
map<string, int>countList;
map<string, int>::iterator it;
queue<string> Q;
我不想贴出 adjacencyList 或 countList 的代码,但这是它们的外观。
//These represent the edges between the two paired nodes
AdjacencyList: (1,2) (1,4) (1,3) (2,4) (2,5) (3,6) (4,6) (4,7) (4,3) (5,4) (5,7) (7,6)
//The first is the node name and the second element is how many edges come into that node.
countList: (1,0) (2,1) (3,2) (4,3) (5,1) (6,3) (7,2)
我的输出应该是:
Queue: 1,2,5,4,3,7,6
//or
Queue: 1,2,5,4,7,3,6
好的,我添加了
countList.at(it->first)--;
在我将顶点推入队列之后。所以这应该将该顶点的计数减少到-1。 这大大缩小了我的输出范围。
好的,现在可以使用了!!! 我将while循环更改为在队列为空后停止并在while循环中打印队列并解决了问题。
我现在的输出是:
Queue: 1, 2, 5, 4, 7, 3, 6,
好的,此代码仅在节点名称仅为单个值时才有效。 对于节点名称长于单个字符的值,我将如何更改 adjList 映射? 也许键值指向一个链表?如果是这样,我该怎么做?
【问题讨论】:
-
除非您保证只有一个入度为 0 的节点(一般情况下不是这样),否则我认为您的基本方法是有缺陷的。如果您有一组关系
{ (a,b), (c,b) },则a和c的入度都为0,但是在处理它们之前不能处理它们中的任何一个(正确的顺序)将是a, c, b或c, a, b)... -
我不知道这是否是为了研究,但有现有的算法。 boost.org/doc/libs/1_42_0/libs/graph/doc/topological_sort.html
-
“countList”的声明是什么?我怀疑“countList.at(a)-+1”行不正确——它似乎没有减少计数器。
-
你能包含完整的输出吗?
标签: c++ sorting loops graph topological-sort