Одна серьезная проблема с вашим существующим кодом - это сбой при вызове его в пустом дереве (root = NULL
).
Вам нужно решить, хотите ли вы иметь в очереди указатели NULL
илине.
Если не они, вы можете ставить в очередь не NULL
значения.
void traverse(Node* root) {
queue<Node*> q;
// no tree no level order.
if(root == NULL) {
return;
}
// push the root to start with as we know it is not NULL.
q.push(root);
// loop till there are nodes in the queue.
while(!q.empty()) {
// dequeue the front node.
Node *tmpNode = q.front();
q.pop();
// print it..we are sure it is not NULL.
cout<<tmpNode->value<<" ";
// enqueue left child if it exists.
if(tmpNode->left) {
q.push(tmpNode->left);
}
// enqueue right child if it exists.
if(tmpNode->right) {
q.push(tmpNode->right);
}
}
}
В качестве альтернативы, если вы решите иметь NULL
в очереди, вы можете сделать:
void traverse(Node* root) {
queue<Node*> q;
// push the root..even if it is NULL.
q.push(root);
// loop till the queue is not empty.
while(!q.empty()) {
// dequeue the front node.
Node *tmpNode = q.front();
q.pop();
// the dequeued pointer can be NULL or can point to a node.
// process the node only if it is not NULL.
if(tmpNode) {
cout<<tmpNode->value<<" ";
q.push(tmpNode->left);
q.push(tmpNode->right);
}
}
}
Первый метод предпочтителен, так как большое дерево имеет множество NULL
дочерних элементов (дочерних элементов конечных узлов), и нет никакого смысла ставить их в очередь, когда мы позже просто не обрабатываем их.