Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 二叉树:迭代顺序打印_C++_Algorithm_Tree_Command Line Interface_Inorder - Fatal编程技术网

C++ 二叉树:迭代顺序打印

C++ 二叉树:迭代顺序打印,c++,algorithm,tree,command-line-interface,inorder,C++,Algorithm,Tree,Command Line Interface,Inorder,我编写了一个红黑树实现,带有内置的顺序遍历(使用嵌套的类迭代器) 我正在寻找一种(迭代的,如果可能的话)算法,它使用顺序遍历以图形方式打印二叉树。 打印方向不相关,即命令行输出中的树可以这样定向(格式化): 2 / \ 1 4 / \ 3 5 |1 | | 2 | |3 | | |4 | |5 RBTree tree; /* Tree init. */ Iterator from(&tree), until(&

我编写了一个红黑树实现,带有内置的顺序遍历(使用嵌套的
类迭代器

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

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

    2
   / \
  1   4
     / \
    3   5
 |1
 |
 |
2
 | |3
 | |
 |4
   |
   |5
RBTree tree;
/* Tree init. */
Iterator from(&tree), until(&tree);
from.first();
until.last();
for (Iterator i = from; i != until; i.next()) {
// PRINTING.
}
或者像这样:

    2
   / \
  1   4
     / \
    3   5
 |1
 |
 |
2
 | |3
 | |
 |4
   |
   |5
RBTree tree;
/* Tree init. */
Iterator from(&tree), until(&tree);
from.first();
until.last();
for (Iterator i = from; i != until; i.next()) {
// PRINTING.
}
或者甚至倒置,但应使用以下提供的方法,使用顺序遍历打印树:

void Iteraor::first(); // Traverses to the first node.
void Iterator::next(); // Traverses to the next node.
void Iterator::last(); // Traverses to the last node.
所以这是可能的,所以做如下的事情:

    2
   / \
  1   4
     / \
    3   5
 |1
 |
 |
2
 | |3
 | |
 |4
   |
   |5
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;
}
我已经研究了a的响应,但是没有一个算法使用顺序遍历(并且大多数是递归的)

编辑:


按照@Nonsesickle的建议,代码被缩减到最小值。

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

  • 如果不在叶上,请将当前节点推到堆栈上,然后移到其最左边的子节点

  • 如果你在一个叶子上,打印它,从堆栈中弹出顶部节点,打印它,然后移动到它最右边的子节点

  • 你继续,直到你的堆栈是空的,你在一个叶子

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

    编辑

    我所说的“一些额外的状态变量”是这样的

    要提供漂亮的打印,您需要跟踪三件事:

  • 当前节点要打印的树的哪个级别(从底部开始计算)。这将告诉您缩进(或从画布边缘偏移)的距离(如果您使用的是二维图形库)

  • 要打印的当前节点是左子节点还是右子节点。这会告诉您(再次)它从其同级缩进的距离,以及连接它和其父级的分支的方向

  • 距离节点“中心”的节点数。这对于与其(非同级)邻居的适当间距也很有用


  • 在迭代状态下进行较少的迭代是可能的,但这对我来说是可行的。

    我不完全确定你的问题是什么。您所做的只是陈述了一些关于代码的事实/观点。您想让我们帮您做什么?我需要一个(可能是迭代的)算法,用于在命令提示符下打印图形二叉树。我会澄清这个问题。好的,这更清楚,但我仍然认为你的问题可以改进一点。特别是,大量的代码将需要大量的时间来消化那些想要帮助的人。将此代码减少到所需的最低限度将使其更有可能得到回答。见和。PS Dobar ti je Engleski…@荒谬是的,我几分钟前把它剪下来了。开玩笑。不管怎样,英语也是唯一的,所以我会回到它。我认为对于漂亮的打印,按顺序遍历并不一定是最佳的,因为您的终端打印的内容更多,所以我建议您在打印策略中尝试这种遍历。看这个。除非你用的是或之类的东西。这听起来不像是图形打印,只是线性的?如果我错了,请纠正我(或澄清答案)。此外,顺序迭代已经实现。我已经用指出的方法更新了这个问题。如果您已经处理了顺序遍历,那么您的问题仍然有点混乱。对比“图形”和“线性”打印是什么意思?我不确定您是否看过输出示例?简单的
    123445
    输出只是排序数组。此外,请检查和它的答案。