Подумайте о простом двоичном дереве, с которого нужно начать:
1
2 3
Обход Эйлера для этого: 1 2 1 3 1
Здесь вы видите шаблон: root, root->left, root, root->right, root
Таким образом, ваш порядок стеков должен быть:
root
root->left
root
root->right
root
Но что, если ваш корень - лист?затем ничего не нажимайте, просто напечатайте значение.
Также, как только вы нажмете узлы слева, направо, убедитесь, что вы установили их как 0
для корня, чтобы вы не продолжали нажимать их вечно.
С учетом вышесказанного код в cpp будет:
Редактировать:
Предыдущий код, который я разместил, содержит ошибку.Ниже приведен правильный код:
void eulerTree(struct Node* root)
{
stack<struct Node*> s;
s.push(root);
while(!s.empty()) {
struct Node* node = s.pop();
visit(node);
if(node->right) {
s.push(node);
s.push(node->right);
}
if(node->left) {
s.push(node);
s.push(node->left);
}
node->left = 0;
node->right = 0;
}
}
Без разрушения дерева:
Но да, даже если код прост, это уничтожает дерево, которое нежелательно.Чтобы решить эту проблему, я собираюсь использовать два свойства для листьев дерева при обходе дерева Эйлера.
Если лист остается дочерним от родителя и правым дочерним от этого родителяимеет значение null
(или)
если лист является правым потомком
- после того, как этот лист напечатан, выведите все родительские узлы вплоть до корня.
Если лист является левым дочерним элементом, а правый дочерний элемент не нулевым
- после печати этого листа выведите только его непосредственного родителя.
Чтобы проиллюстрировать это, посмотрите на дерево ниже.
1
2 3
4 5 6 7
Если лист равен 5
, то после его печати распечатайте всех родителей до 1
.
Если лист равен 4
, то после его печати выведите только его непосредственного родителя 2
.
Чтобы упростить реализацию, я собираюсь использовать родительский стек в дополнение к текущемустек.
void eulerTree(struct Node* root) {
stack<struct Node*> s;
s.push(root);
struct Node* original = root;
stack<struct Node*> p;
while(!s.empty()) {
struct Node* node = s.top();
s.pop();
visit(node);
if ( !node->right && !node->left && !p.empty() ) {
struct Node* pNode = p.top();
if ( pNode->left == node && !pNode->right || pNode->right == node ) {
while ( !p.empty() ) {
visit(p.top());
p.pop();
}
p.push(original);
} else {
visit(pNode);
}
}
if(node->left || node->right) {
p.push(node);
}
if(node->right) {
s.push(node->right);
}
if(node->left) {
s.push(node->left);
}
}
}