制作二叉树

时间:2016-09-11 12:30:27

标签: c++ binary-tree

我得到了一个完整二叉树的链表表示,格式如下:

diagram

我必须将链表转换为完整的二叉树。我正在使用队列来做同样的事情。我将根存储在队列中,将其存储在一个变量中,指向我正在制作的新节点然后存储左右指针再次执行此操作,但是当在自制树上执行前序遍历时,我只获得一个节点作为输出。例如。链接列表是1-> 2-> 3-> 4-> 5-> NULL但是在前序遍历中我得到1作为输出。

void convert(node *head,TreeNode * &root)
 {
     if(head==NULL){
        root=NULL;
        return;
    }
    queue<struct TreeNode* >Q;
    Q.push(root);     // Pushing root which is Null at start.
    while(head!=NULL){
        struct TreeNode * x=Q.front();     // storing
        Q.pop();                   //Popping
        x=new TreeNode;           //pointing this null pointer to a new node 
        x->data=head->data;      // storing data
        x->left=NULL;           //Making left of this point to NuLL
        x->right=NULL;         //Making right of this point to NuLL
        if(!root)root=x;      // If root is null point it to x.
        Q.push(x->left);      // Push the left child pointer which is NULL
        Q.push(x->right);     // Push the right child pointer which is NULL
        head=head->next;    // Move further in linked list.
     }
  }

1 个答案:

答案 0 :(得分:0)

我没有发布完整的答案,但我会提供一些调试帮助。

以下是循环的第一个树迭代,以及有关变量如何变化的注释 (当你在脑海中追踪程序时,将这样的事情写在纸上是一个非常好的主意。它比调试器视图更不瞬态,并且能够在调试时及时移回是有价值的。)

queue<struct TreeNode* >Q;          // Q: []
Q.push(root);                       // Q: [NULL]
while(head!=NULL){
    struct TreeNode * x=Q.front();  // x = NULL, Q: [NULL]
    Q.pop();                        // Q: []
    x=new TreeNode;                 // x: -> TreeNode {}
    x->data=head->data;             // 
    x->left=NULL;                   // 
    x->right=NULL;                  // x: ->TreeNode {data: data of initial head, 
                                    //                left: NULL, right:NULL}
    if(!root)root=x;                // root: ->TreeNode {data: data of initial head, 
                                    //                   left: NULL, right:NULL}
    Q.push(x->left);                // Q: [NULL]
    Q.push(x->right);               // Q: [NULL, NULL]
    head=head->next;                // Move further in linked list.
}
{
    struct TreeNode * x=Q.front();  // x = NULL, Q: [NULL, NULL]
    Q.pop();                        // Q: [NULL]
    x=new TreeNode;                 // x: -> TreeNode {}
    x->data=head->data;             // 
    x->left=NULL;                   // 
    x->right=NULL;                  // x: ->TreeNode {data: head->data, left: NULL, right:NULL}
    if(!root)root=x;                // root: still ->TreeNode {data: data of initial head, 
                                    //                         left: NULL, right:NULL}
    Q.push(x->left);                // Q: [NULL, NULL]
    Q.push(x->right);               // Q: [NULL, NULL, NULL]
    head=head->next;                // Move further in linked list.
}
{
    struct TreeNode * x=Q.front();  // x = NULL, Q: [NULL, NULL, NULL]
    Q.pop();                        // Q: [NULL, NULL]
    x=new TreeNode;                 // x: -> TreeNode {}
    x->data=head->data;             // 
    x->left=NULL;                   // 
    x->right=NULL;                  // x: ->TreeNode {data: head->data, left: NULL, right:NULL}
    if(!root)root=x;                // root: still ->TreeNode {data: data of initial head, 
                                    //                         left: NULL, right:NULL}
    Q.push(x->left);                // Q: [NULL, NULL, NULL]
    Q.push(x->right);               // Q: [NULL, NULL, NULL, NULL]
    head=head->next;                // Move further in linked list.
}

正如您所看到的,您正在推送并弹出一系列空指针到队列中 您永远不会将队列中的值用于任何事情。

为了澄清这个问题,假设你有一个整数队列并且这样做了:

struct S { int x; };
S s;
s.x = 0;
queue<int> q;
q.push(s.x);
int y = q.front();
y = 96;

我很确定您不会期望s.x的价值突然变为96而不是0。 指针以完全相同的方式工作。

您也永远不会修改您创建的根节点,这就是您只获得单节点树(其他节点只是内存泄漏)的原因。

你可以

  • 弹出树节点指针
  • 从列表中获取下一个两个元素(如果存在)
  • 根据需要从列表元素中创建新节点
  • 将弹出节点的左右指针设置为这两个新指针
  • 将新指针推入队列
  • 重复