将节点添加到完整的树

时间:2018-05-29 07:45:01

标签: c++ tree nodes complete

尝试在C ++中从头开始制作完整的树

1st node = root
2nd node = root->left
3rd node = root->right
4th node = root->left->left
5th node = root->left->right
6th node = root->right->left
7th node = root->right->right

树看起来像这样:

                 NODE
              /        \
          NODE          NODE
       /        \    /        \
    NODE      NODE  NODE      NODE
    /
NEXT NODE HERE

我将如何检测下一个节点的位置,以便我可以使用一个函数添加新节点?例如,第8个节点将被放置在root-> left-> left-> left

目标是将100个节点放入树中,其中包含一个简单的for循环,其中包含“insert(Node * newnode)”,而不是一次执行。它会变成像丑陋的东西:

100th node = root->right->left->left->right->left->left

4 个答案:

答案 0 :(得分:2)

使用队列数据结构来完成构建完整的二叉树。 STL提供std::queue

示例代码,其中函数将在您请求时在循环中使用。我假设已经创建了队列(即为其分配了内存):

// Pass double pointer for root, to preserve changes
void insert(struct node **root, int data, std::queue<node*>& q)
{
    // New 'data' node
    struct node *tmp = createNode(data);

    // Empty tree, initialize it with 'tmp'
    if (!*root)
        *root = tmp;
    else
    {
        // Get the front node of the queue.
        struct node* front = q.front();

        // If the left child of this front node doesn’t exist, set the
        // left child as the new node.
        if (!front->left)
            front->left = tmp;

        // If the right child of this front node doesn’t exist, set the
        // right child as the new node.
        else if (!front->right)
            front->right = tmp;

        // If the front node has both the left child and right child, pop it.
        if (front && front->left && front->right)
            q.pop();
    }

    // Enqueue() the new node for later insertions
    q.push(tmp);
}

答案 1 :(得分:1)

假设root是节点#1,root的子节点是节点#2,节点#3,依此类推。然后可以使用以下算法找到节点#k的路径:

  1. 将k表示为二进制值k = { k_{n-1}, ..., k_0 },其中每个k_i为1位,i = {n-1} ... 0
  2. 需要n-1步骤从根到节点#k,由k_{n-2},...,k_0的值指示,其中
    1. if k_i = 0然后左转
    2. if k_i = 1然后右转
  3. 例如,要在完整的树中插入节点#11(二进制1011),您可以将其插入root-&gt; left-&gt; right-&gt; right(按照{{1}的指示二进制文件011)。

    使用上面的算法,编写一个函数应该是直截了当的,给定任何k,将完整树中的节点#k插入到正确的位置。只要检测到新节点被正确创建(即分别为正确的左或右子节点),节点甚至不需要按顺序插入。

答案 2 :(得分:1)

假设树总是完整的,我们可以使用下一个递归。它没有提供最佳性能,但很容易理解

Node* root;
Node*& getPtr(int index){
    if(index==0){
       return root;    
    }
    if(index%2==1){
       return (getPtr( (index-1)/2))->left;
    }
    else{
       return (getPtr( (index-2)/2))->right;
    }
}

然后你就像

一样使用它
for(int i = 0; i<100; ++i){
  getPtr(i) = new Node( generatevalue(i) );
}

答案 3 :(得分:0)

 private Node addRecursive(*Node current, int value) {
    if (current == null) {
        return new Node(value);
    }

    if (value < current.value) {
        current->left = addRecursive(current->left, value);
    } else if (value > current->value) {
        current->right = addRecursive(current->right, value);
    } else {
        // value already exists
        return current;
    }

    return current;
 }

我不知道如果你的节点有一个值实例,但是: 使用此代码,您可以从根目录开始排序二进制树。 如果新节点的值低于当前节点的值,我们转到左子节点。如果新节点的值大于当前节点的值,我们将转到正确的子节点。当前节点为null时,我们已到达叶节点,我们可以将新节点插入该位置。