树结构-不正确的子级 我试图在C++中构造简单的结构。它应该类似于AVL树
当我在main()函数中构建一个包含三个节点的简单树时,一切都正常 问题是当我尝试使用insert()函数时。此函数的第一个参数包含将第二个参数的值放在何处的信息 代码如下:树结构-不正确的子级 我试图在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
#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阻止了该站点,因此我无法查看您的代码。所以即使我想帮忙,我也不能。请在这里发布一个小的可复制的问题示例,并具体解释什么不起作用