假设您想递归地实现一个二叉树的宽度优先搜索。你会怎么做?
是否可以只使用调用堆栈作为辅助存储?
假设您想递归地实现一个二叉树的宽度优先搜索。你会怎么做?
是否可以只使用调用堆栈作为辅助存储?
当前回答
Java中简单的BFS和DFS递归: 只需要在堆栈/队列中推送/提供树的根节点并调用这些函数。
public static void breadthFirstSearch(Queue queue) {
if (queue.isEmpty())
return;
Node node = (Node) queue.poll();
System.out.println(node + " ");
if (node.right != null)
queue.offer(node.right);
if (node.left != null)
queue.offer(node.left);
breadthFirstSearch(queue);
}
public static void depthFirstSearch(Stack stack) {
if (stack.isEmpty())
return;
Node node = (Node) stack.pop();
System.out.println(node + " ");
if (node.right != null)
stack.push(node.right);
if (node.left != null)
stack.push(node.left);
depthFirstSearch(stack);
}
其他回答
愚蠢的方式:
template<typename T>
struct Node { Node* left; Node* right; T value; };
template<typename T, typename P>
bool searchNodeDepth(Node<T>* node, Node<T>** result, int depth, P pred) {
if (!node) return false;
if (!depth) {
if (pred(node->value)) {
*result = node;
}
return true;
}
--depth;
searchNodeDepth(node->left, result, depth, pred);
if (!*result)
searchNodeDepth(node->right, result, depth, pred);
return true;
}
template<typename T, typename P>
Node<T>* searchNode(Node<T>* node, P pred) {
Node<T>* result = NULL;
int depth = 0;
while (searchNodeDepth(node, &result, depth, pred) && !result)
++depth;
return result;
}
int main()
{
// a c f
// b e
// d
Node<char*>
a = { NULL, NULL, "A" },
c = { NULL, NULL, "C" },
b = { &a, &c, "B" },
f = { NULL, NULL, "F" },
e = { NULL, &f, "E" },
d = { &b, &e, "D" };
Node<char*>* found = searchNode(&d, [](char* value) -> bool {
printf("%s\n", value);
return !strcmp((char*)value, "F");
});
printf("found: %s\n", found->value);
return 0;
}
如果使用数组来支持二叉树,则可以用代数方法确定下一个节点。如果I是一个节点,那么它的子节点可以在2i + 1(左节点)和2i + 2(右节点)处找到。节点的下一个邻居由i + 1给出,除非i是2的幂
下面是在数组支持的二叉搜索树上实现宽度优先搜索的伪代码。这假设一个固定大小的数组,因此一个固定深度的树。它将查看无父节点,并可能创建难以管理的大堆栈。
bintree-bfs(bintree, elt, i)
if (i == LENGTH)
return false
else if (bintree[i] == elt)
return true
else
return bintree-bfs(bintree, elt, i+1)
Java中简单的BFS和DFS递归: 只需要在堆栈/队列中推送/提供树的根节点并调用这些函数。
public static void breadthFirstSearch(Queue queue) {
if (queue.isEmpty())
return;
Node node = (Node) queue.poll();
System.out.println(node + " ");
if (node.right != null)
queue.offer(node.right);
if (node.left != null)
queue.offer(node.left);
breadthFirstSearch(queue);
}
public static void depthFirstSearch(Stack stack) {
if (stack.isEmpty())
return;
Node node = (Node) stack.pop();
System.out.println(node + " ");
if (node.right != null)
stack.push(node.right);
if (node.left != null)
stack.push(node.left);
depthFirstSearch(stack);
}
我认为这可以使用指针来完成,而不使用任何队列。
基本上我们在任何地方都维护两个指针,一个指向父结点,另一个指向待处理的子结点(链接列表指向所有已处理的子结点)
现在你只需分配子进程的指针&当父进程处理完成时,你只需让子进程成为父进程进行下一层的处理
以下是我的代码:
//Tree Node
struct Node {
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next)
: val(_val), left(_left), right(_right), next(_next) {}
};
/ / Algorightm:
void LevelTraverse(Node* parent,Node* chidstart,Node* childend ){
if(!parent && !chidstart) return; // we processed everything
if(!parent && chidstart){ //finished processing last level
parent=chidstart;chidstart=childend=NULL; // assgin child to parent for processing next level
LevelTraverse(parent,chidstart,childend);
}else if(parent && !chidstart){ // This is new level first node tobe processed
Node* temp=parent; parent=parent->next;
if(temp->left) { childend=chidstart=temp->left; }
if(chidstart){
if(temp->right) { childend->next=temp->right; childend=temp->right; }
}else{
if(temp->right) { childend=chidstart=temp->right; }
}
LevelTraverse(parent,chidstart,childend);
}else if(parent && chidstart){ //we are in mid of some level processing
Node* temp=parent; parent=parent->next;
if(temp->left) { childend->next=temp->left; childend=temp->left; }
if(temp->right) { childend->next=temp->right; childend=temp->right; }
LevelTraverse(parent,chidstart,childend);
}
}
//驱动代码:
Node* connect(Node* root) {
if(!root) return NULL;
Node* parent; Node* childs, *childe; parent=childs=childe=NULL;
parent=root;
LevelTraverse(parent, childs, childe);
return root;
}
下面是一个python实现:
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
def bfs(paths, goal):
if not paths:
raise StopIteration
new_paths = []
for path in paths:
if path[-1] == goal:
yield path
last = path[-1]
for neighbor in graph[last]:
if neighbor not in path:
new_paths.append(path + [neighbor])
yield from bfs(new_paths, goal)
for path in bfs([['A']], 'D'):
print(path)