在C++中使用队列构造二叉树

Constructing a binary tree using queue in C++

本文关键字:二叉树 队列 C++      更新时间:2023-10-16

我正在尝试用C++编写一些数据结构硬件。当我尝试使用队列构建二叉树时,我不知何故对指针问题感到困惑。

class Tree{
private:
    struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
public:
    TreeNode* root = NULL;       
    Tree();
    Tree(queue<int>& val);       
    ~Tree();
    string toString_bf();
};

Tree(queue<int> &vals){
    if (vals.empty())
        return;
    root = new TreeNode(vals.front());
    vals.pop();
    queue<TreeNode**> pts;       // what is the meaning of this? Why should use pointers to pointer?
    pts.push(&(root->left));     // also have doubts here, about the reference used in the parameter
    pts.push(&(root->right));
    while (!vals.empty()){
        TreeNode* t = new TreeNode(vals.front());
        *(pts.front()) = t;      // and here
        pts.pop();
        vals.pop();
        pts.push(&(t->left));
        pts.push(&(t->right));
    }
}

按照我的理解,左和右都是指针,为什么不能直接传递给它们?

变量pts是指向稍后需要放置子树的位置的指针队列。这些位置本身就是指向TreeNode的指针(每个位置都是leftright数据类型为 TreeNode * 的数据成员(,因此您需要一个TreeNode **来指向它们是有意义的。

换句话说,每次执行*(pts.front()) = t;时,都会将先前构造的TreeNodeleftright成员设置为指向最近构造的节点。

你可以做一个typedef TreeNode *TreePtr;,也许使用它看起来更干净。


为了进一步澄清正在发生的事情:

每次"while"循环启动时:

  • root 是正在构建的树的根,包含 n+1 个节点,每个节点保存一个从输入队列vals中获取的值(其中 n 是 while 循环已经运行的次数(

  • vals包含尚未放入树中的所有剩余值(如果有(

  • pts 包含一组指向树中节点内的指针的指针;它包含指向尚未分配子树的所有指针的指针;其中有 n+2 个。
因此,每个循环创建一个新节点,使其中一个未分配的指针指向新节点

,然后将新节点的未分配指针添加到队列中。

请注意,当操作结束时,pts 中总是有 n+2 个指针,这些指针将被丢弃。通过知道需要多少节点( = vals.size(((,一旦完成足够的节点,就可以停止执行pts.push操作,从而将所需的临时空间量减少约 50%:

      vals.pop();
      if( pts.size() < vals.size()) {
           pts.push(&(t->left));
           pts.push(&(t->right))
       } // otherwise we have enough for all remaining vals.