树结构-不正确的子级 我试图在C++中构造简单的结构。它应该类似于AVL树

树结构-不正确的子级 我试图在C++中构造简单的结构。它应该类似于AVL树,c++,tree,C++,Tree,当我在main()函数中构建一个包含三个节点的简单树时,一切都正常 问题是当我尝试使用insert()函数时。此函数的第一个参数包含将第二个参数的值放在何处的信息 代码如下: #include <numeric> #include <vector> #include <cstdio> #include <cstdlib> using namespace std; struct Node { Node* left; Node* ri

当我在main()函数中构建一个包含三个节点的简单树时,一切都正常

问题是当我尝试使用insert()函数时。此函数的第一个参数包含将第二个参数的值放在何处的信息

代码如下:

#include <numeric>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct Node {
    Node* left;
    Node* right;
    Node* parent;
    int value;
    int count_leafs;
    int height;
};

Node* root;


void insert2(int p, int value, Node* node, int left) 
{
    //printf("insert %d %d - (%d, %d) %d \n", p, value, node->left, node->right, left);

    if (root == NULL) {
        //  creating a tree root

        Node new_node;
        new_node.left = NULL;
        new_node.right = NULL;
        new_node.parent = NULL;

        root = &new_node;

        root->value = value;
        root->count_leafs = 1;
        root->height = 1;
        return;
    }

    if (node->left == NULL && node->right == NULL) {
        //  joining value to the leaf

        Node new_parent;
        new_parent.count_leafs = 2;
        new_parent.height = 2;
        new_parent.value = node->value + value;
        new_parent.parent = node->parent;
        new_parent.left = NULL;
        new_parent.right = NULL;

        Node new_leaf;
        new_leaf.value = value;
        new_leaf.count_leafs = 1;
        new_leaf.left = NULL;
        new_leaf.right = NULL;
        new_leaf.height = 1;
        new_leaf.parent = &new_parent;

        new_parent.left = &new_leaf;
        new_parent.right = node;


        if (node->parent != NULL && node->parent->left != NULL && node->parent->left == node) {
            printf("a");
            node->parent->left = &new_parent;
        }

        if (node->parent != NULL && node->parent->right != NULL && node->parent->right == node) {
            printf("b");
            node->parent->right = &new_parent;  
        }

        node->parent = &new_parent;

        return;
    }

    //printf("GOTO: %d %d \n", left + node->left->count_leafs, p);

    node->value += value;
    node->count_leafs += 1;

    if (left + node->left->count_leafs + 1 >= p) {
        //printf("W left\n");
        insert2(p, value, node->left, left);
    } else {    
        //printf("W right\n");
        insert2(p, value, node->right, left + node->left->count_leafs);
    }
}


void insert(int p, int value) 
{
    insert2(p, value, root, 0);
}

int main() 
{
    Node new_root;
    root = NULL;

    new_root.value = 10;
    new_root.height = 2;
    new_root.count_leafs = 2;
    new_root.parent = NULL;
    root = &new_root;

    Node left;
    left.value = 6;
    left.height = 1;
    left.count_leafs = 1;
    left.parent = root;
    left.left = NULL;
    left.right = NULL;

    Node right;
    right.value = 4;
    right.height = 1;
    right.count_leafs = 1;
    right.parent = root;
    right.left = NULL;
    right.right = NULL;

    root->left = &left;
    root->right = &right;

    // PLACE A

    insert(0, 1);

    // PLACE B

    return 0;
}
接下来,在位置a和位置B之间的一行中,我想添加一个新节点。之后(在位置B),树应如下所示:

    11
   /  \
  7    4
 / \
1   6
            11
           /  \
  1972250912   4
     / \
    2   2
if (root == NULL) 
{
    Node new_node;
    root = &new_node;
    return;
}
但我得到的是这样的东西:

    11
   /  \
  7    4
 / \
1   6
            11
           /  \
  1972250912   4
     / \
    2   2
if (root == NULL) 
{
    Node new_node;
    root = &new_node;
    return;
}
我想不出是怎么回事。这应该是insert2()函数中的问题,但我找不到它

你看到了吗?
提前感谢您的帮助

这种行为的原因是您在范围外使用了范围变量。不能使用指向超出该范围的范围变量的指针。范围变量仅存在于声明它们的范围内。如果决定访问范围外的范围变量,您将访问堆栈的某个部分,该堆栈将使其他一些数据覆盖该变量,从而导致未定义的行为

我的意思是,你不能这样做:

    11
   /  \
  7    4
 / \
1   6
            11
           /  \
  1972250912   4
     / \
    2   2
if (root == NULL) 
{
    Node new_node;
    root = &new_node;
    return;
}
您可以使用操作符new在堆中创建struct节点的新实例,并在以后使用它

if (root == NULL) 
{
    root = new Node;
    return;
}
但您必须稍后删除此节点。或者您可以使用智能指针,请参阅

阅读和了解更多信息

下面的代码正是您所期望的。但是,它不会删除会导致内存泄漏的已创建节点,因此必须改进此代码,但这是一个单独的问题

#include <numeric>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;

struct Node {
    Node* left;
    Node* right;
    Node* parent;
    int value;
    int count_leafs;
    int height;
};

Node* root;


void insert2(int p, int value, Node* node, int left)
{
    //printf("insert %d %d - (%d, %d) %d \n", p, value, node->left, node->right, left);

    if (root == NULL) {
        //  creating a tree root

        Node* new_node = new Node;
        new_node->left = NULL;
        new_node->right = NULL;
        new_node->parent = NULL;

        root = new_node;

        root->value = value;
        root->count_leafs = 1;
        root->height = 1;
        return;
    }

    if (node->left == NULL && node->right == NULL) {
        //  joining value to the leaf

        Node* new_parent = new Node;
        new_parent->count_leafs = 2;
        new_parent->height = 2;
        new_parent->value = node->value + value;
        new_parent->parent = node->parent;
        new_parent->left = NULL;
        new_parent->right = NULL;

        Node* new_leaf = new Node;
        new_leaf->value = value;
        new_leaf->count_leafs = 1;
        new_leaf->left = NULL;
        new_leaf->right = NULL;
        new_leaf->height = 1;
        new_leaf->parent = new_parent;

        new_parent->left = new_leaf;
        new_parent->right = node;


        if (node->parent != NULL && node->parent->left != NULL && node->parent->left == node) {
            printf("a");
            node->parent->left = new_parent;
        }

        if (node->parent != NULL && node->parent->right != NULL && node->parent->right == node) {
            printf("b");
            node->parent->right = new_parent;
        }

        node->parent = new_parent;

        return;
    }

    //printf("GOTO: %d %d \n", left + node->left->count_leafs, p);

    node->value += value;
    node->count_leafs += 1;

    if (left + node->left->count_leafs + 1 >= p) {
        //printf("W left\n");
        insert2(p, value, node->left, left);
    }
    else {
        //printf("W right\n");
        insert2(p, value, node->right, left + node->left->count_leafs);
    }
}


void insert(int p, int value)
{
    insert2(p, value, root, 0);
}

int main()
{
    Node new_root;
    root = NULL;

    new_root.value = 10;
    new_root.height = 2;
    new_root.count_leafs = 2;
    new_root.parent = NULL;
    root = &new_root;

    Node left;
    left.value = 6;
    left.height = 1;
    left.count_leafs = 1;
    left.parent = root;
    left.left = NULL;
    left.right = NULL;

    Node right;
    right.value = 4;
    right.height = 1;
    right.count_leafs = 1;
    right.parent = root;
    right.left = NULL;
    right.right = NULL;

    root->left = &left;
    root->right = &right;

    // PLACE A

    insert(0, 1);

    // PLACE B

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
结构节点{
节点*左;
节点*右;
节点*父节点;
int值;
int count_leafs;
内部高度;
};
节点*根;
void insert2(int p,int值,节点*节点,int左)
{
//printf(“插入%d%d-(%d,%d)%d\n”,p,值,节点->左,节点->右,左);
if(root==NULL){
//创建树根
Node*new_Node=新节点;
新建_节点->左=空;
新建_节点->右=空;
新建_节点->父节点=NULL;
根=新的_节点;
根->值=值;
root->count\u leafs=1;
根->高度=1;
返回;
}
if(node->left==NULL&&node->right==NULL){
//将值连接到叶
Node*new_parent=新节点;
新建父项->计数\u leafs=2;
新建父项->高度=2;
新建父节点->值=节点->值+值;
新建父节点->父节点=节点->父节点;
新建父项->左=空;
新建父项->右=空;
Node*new_leaf=新节点;
新叶->值=值;
新建页面->计数页面=1;
新建叶->左=空;
新建叶->右=空;
新叶->高度=1;
新建\u叶->父级=新建\u父级;
新建父项->左=新建叶;
新建父节点->右=节点;
如果(节点->父节点!=NULL&&node->parent->left!=NULL&&node->parent->left==node){
printf(“a”);
节点->父节点->左=新父节点;
}
如果(节点->父节点!=NULL&&node->parent->right!=NULL&&node->parent->right==node){
printf(“b”);
节点->父节点->右=新父节点;
}
节点->父节点=新父节点;
返回;
}
//printf(“转到:%d%d\n”,左+节点->左->计数,p);
节点->值+=值;
节点->计数\u叶数+=1;
如果(左+节点->左->计数+1>=p){
//printf(“W left\n”);
插入2(p,值,节点->左,左);
}
否则{
//printf(“W right\n”);
插入2(p,值,节点->右,左+节点->左->计数);
}
}
无效插入(int p,int值)
{
插入2(p,值,根,0);
}
int main()
{
新根节点;
root=NULL;
新的_root.value=10;
新根高度=2;
new_root.count_leafs=2;
new_root.parent=NULL;
root=&new_root;
左淋巴结;
左。数值=6;
左。高度=1;
left.count_leafs=1;
left.parent=根;
left.left=NULL;
left.right=NULL;
节点权;
右值=4;
右高=1;
right.count_leafs=1;
right.parent=root;
right.left=NULL;
right.right=NULL;
根->左=&left;
根->右=&右;
//放置
插入(0,1);
//地点B
返回0;
}
Reason#948452为了不将代码链接到第三方站点,工作中的VPN阻止了该站点,因此我无法查看您的代码。所以即使我想帮忙,我也不能。请在这里发布一个小的可复制的问题示例,并具体解释什么不起作用