gpt4 book ai didi

c++ - 二叉树 : iterative inorder print

转载 作者:太空狗 更新时间:2023-10-29 23:00:23 24 4
gpt4 key购买 nike

我已经编写了一个红黑树实现,具有内置的顺序遍历(使用嵌套的 class Iterator)。

我正在寻找一种(迭代,如果可能的话)算法,该算法使用中序遍历以图形方式打印二叉树。

打印方向不相关,即命令行输出中的树可以像这样定向(格式化):

    2
/ \
1 4
/ \
3 5

或者像这样:

 |1
|
|
2
| |3
| |
|4
|
|5

甚至是颠倒的,但是应该使用 in-oder 遍历打印树,使用下面提供的方法:

void Iteraor::first(); // Traverses to the first node.
void Iterator::next(); // Traverses to the next node.
void Iterator::last(); // Traverses to the last node.

所以有可能做这样的事情:

RBTree tree;
/* Tree init. */
Iterator from(&tree), until(&tree);
from.first();
until.last();
for (Iterator i = from; i != until; i.next()) {
// PRINTING.
}

这是原始代码:

/** A program for Red-Black Tree manipulation: insertion and value retrieval.
* All position relations (first, last, previous, next) are in-order.
*/

class RBTree {
struct Node {
enum class Colour : bool { RED, BLACK };
int value;
Node *left, *right, *parent;
Colour colour;
public:
/* ... */
};
class Iterator {
class Stack {
/* ... */
};
Stack stack;
const RBTree* const tree; // Once set, neither the reference nor the referenced object's attributes can be modified.
Node* pointer;
public:
Iterator(const RBTree*);
void first();
void next();
void last();
/* ... */
Node* getNode() const;
bool operator != (const Iterator&) const;
};
Node *root;
Iterator iterator;
public:
RBTree() : root(nullptr), iterator(this) {}
/* ... */
bool printTree() const;
~RBTree() { deleteTree(); }
};

// TREE // public: //

/* ... */

bool RBTree::printTree() const {
if (root != nullptr) {
// print ??
return true;
}
else
return false;

}

// NODE: Ensures the proper connection. //

void RBTree::Node::setLeft(Node *p_left) {
left = p_left;
if (p_left != nullptr)
p_left->parent = this;
}

void RBTree::Node::setRight(Node *p_right) {
right = p_right;
if (p_right != nullptr)
p_right->parent = this;
}

// ITERATOR //

RBTree::Iterator::Iterator(const RBTree* p_tree) : tree(p_tree), pointer(p_tree->root) {}

// Traverses to the first node (leftmost).
void RBTree::Iterator::first() {
if (pointer != nullptr) {
while (true) {
if (pointer != nullptr) {
stack.push(pointer);
pointer = pointer->left;
}
else {
pointer = stack.peek();
break;
}
}
}
}

// Traverses to next node in-order.
void RBTree::Iterator::next() {
if (pointer != nullptr) {
if (!stack.isEmpty()) {
pointer = stack.pop();
if (pointer->right != nullptr) {
pointer = pointer->right;
first();
}
}
}
}

// Traverses to the last node (rightmost).
void RBTree::Iterator::last() {
pointer = tree->root;
if (pointer != nullptr)
while (pointer->right != nullptr)
pointer = pointer->right;
stack.clear();
}

/* ... */

RBTree::Node* RBTree::Iterator::getNode() const {
return pointer;
}

bool RBTree::Iterator::operator != (const Iterator& p_iterator) const {
return pointer != p_iterator.pointer ? true : false;
}

我已经研究了 similar question 的回复, 但是没有一个算法利用了中序遍历(而且大部分都是递归的)。

编辑:

按照@nonsensickle 的建议,代码被精简到最低限度。

最佳答案

使用迭代算法进行中序遍历的规范方法是维护需要打印的节点的堆栈(或后进先出队列)。每个循环迭代做两件事之一:

  1. 如果您不在叶节点上,则将当前节点压入堆栈并移动到其最左边的子节点。

  2. 如果您在一片叶子上,打印它,从堆栈中弹出顶部节点,打印它,然后继续到它最右边的 child 。

你继续,直到你的堆栈为空并且你在一片叶子上。

节点间分支的格式和图形表示的生成显然取决于您。请记住,它需要一些额外的状态变量。

编辑

我所说的“一些额外的状态变量”是这个意思。

要提供 pretty-print ,您需要跟踪三件事:

  1. 您当前要打印的节点位于树的哪个级别(从底部开始计算)。这会告诉您(部分)缩进多远(或者如果您使用的是 2D 绘图库,它会从 Canvas 的边缘偏移)。

  2. 您当前要打印的节点是左子节点还是右子节点。这会(再次)告诉您它与其兄弟之间的缩进距离,以及连接它与父级的分支的方向。

  3. 您的节点距离“中心”有多少个节点。这对于与其(非兄弟)邻居的适当间距也很有用。

可能可以使用较少的迭代到迭代状态,但这对我有用。

关于c++ - 二叉树 : iterative inorder print,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33769837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com