【发布时间】:2019-08-17 14:40:46
【问题描述】:
我有一个看起来像这样的 Trie:
Root
/ \
b c
/ / \
a a h
/ / / \
t t a e
/ /
t e
/ \
r s
/ \
s e
我正在尝试实现 DFS 和 BFS。 BFS 工作正常,使用队列:
public String breadthFirstSearch() {
//FIFO Queue to hold nodes
Queue<TrieNode> nodeQueue = new LinkedList<TrieNode>();
//Output array
ArrayList<Integer> out = new ArrayList<Integer>();
//Start from root
nodeQueue.add(this.root);
//While queue is not empty
while (nodeQueue.isEmpty() == false) {
//Remove and return first queue element
TrieNode current = nodeQueue.poll();
//For node's children
for (int i=0; i<26; i++) {
//If not null
if (current.offspring[i] != null) {
//Add node to queue
nodeQueue.add(current.offspring[i]);
//Add node's index (char) to output array
out.add(i);
}
}
}
//Return result
return indexArrayToString(out);
}
输出:
b,c,a,a,h,t,t,a,e,t,e,r,s,s,e
现在,我正在尝试实现 DFS(相同的算法,但使用堆栈)但是输出不正确:
public String depthFirstSearch() {
//LIFO Stack to hold nodes
Stack<TrieNode> nodeStack = new Stack<TrieNode>();
//Output array
ArrayList<Integer> out = new ArrayList<Integer>();
//Start from root
nodeStack.push(this.root);
//While stack is not empty
while (nodeStack.isEmpty() == false) {
//Remove and return first stack element
TrieNode current = nodeStack.pop();
//For node's children
for (int i=0; i<26; i++) {
//If not null
if (current.offspring[i] != null) {
//Add node to stack
nodeStack.push(current.offspring[i]);
//Add node's index (char) to output array
out.add(i);
}
}
}
//Return result
return indexArrayToString(out);
}
这给出了:
b,c,a,h,a,e,e,r,s,e,s,t,t,a,t
当我希望它给予时:
t,a,b,t,a,t,a,s,r,e,s,e,e,h,c
我不知道出了什么问题。
【问题讨论】:
-
专业提示:使用递归实现 DFS 通常比使用显式堆栈更简单。
-
@Charlie 你要实现后序DFS遍历吗?
-
与其打电话给
indexArrayToString(out),不如直接打电话给out.toString()? -
为了将堆栈用于后序 DFS,您应该从堆栈中弹出节点并在稍后的某个时间将其 char 放入“out”数组中(即不是在您发现它们之后)。您的 trie 节点似乎没有 char 字段。如果 BFS 不是问题,因为您在发现时输出了字符,因此您可以使用整数“i”来表示这些字符。在后序 DFS 中,除非您知道节点实际包含哪个字符,否则您不能这样做。
-
可以维护一个 Map
或 Map 并在我们发现一个新的 trienode 时填充它,但实际上在 TrieNode 类中没有一个 char 字段看起来很尴尬