C++ 二叉搜索树插入垃圾数据

C++ 二叉搜索树插入垃圾数据,c++,insert,binary-search-tree,C++,Insert,Binary Search Tree,所以,我正在为一个项目编写一个自平衡二叉搜索树,我似乎对插入函数有问题。具体来说,这段代码如下: if(element > n->data) { n->rightChild = insert(n->rightChild, element); } 出于测试的目的,我只使用insert(root,10)insert(root,20)insert(root,30)等等。但问题发生在insert 30。它通过并尝试用另一个非空子树替换一个非空子树(20)。我不确定

所以,我正在为一个项目编写一个自平衡二叉搜索树,我似乎对插入函数有问题。具体来说,这段代码如下:

if(element > n->data)
{
    n->rightChild = insert(n->rightChild, element);
}   
出于测试的目的,我只使用insert(root,10)insert(root,20)insert(root,30)等等。但问题发生在insert 30。它通过并尝试用另一个非空子树替换一个非空子树(20)。我不确定为什么我会遇到这个问题,因为递归是我看到这个实现的唯一方式,在我发现的所有其他类似问题中,答案的编码方式要么与此类似,要么与此完全相同。有人能帮我弄清楚发生了什么事吗?目前,在它尝试用30覆盖20子树之后,它最终用垃圾数据填充根右子树,然后,当它尝试重新平衡时,抛出EXC_BAD_访问错误,可能是因为我试图访问一个不存在的节点

源代码
#包括
使用名称空间std;
结构节点
{
公众:
int数据,高度;
节点*leftChild,*rightChild;
};
int findMin(struct node*p)//查找树中最小的节点
{
while(p->leftChild!=NULL)
p=p->leftChild;
返回p->数据;
}
int findMax(struct node*p)//查找树中最大的节点
{
while(p->rightChild!=NULL)
p=p->rightChild;
返回p->数据;
}
int max(int a,int b)//获取两个整数的最大值
{
如果(a>b)
返回a;
其他的
返回b;
}
int height(struct node*p)//获取树的高度
{
内lHeight,rHeight;
if(p==NULL)
返回-1;
其他的
{
lHeight=高度(p->leftChild);
rHeight=高度(p->rightChild);
如果(lHeight>rHeight)
返回lHeight+1;
其他的
返回rHeight+1;
}
}
struct node*newNode(int元素)//用于返回带有空子树的新节点的helper函数
{
node*newPtr=(struct node*)malloc(sizeof(newPtr));
newPtr->data=元素;
newPtr->leftChild=NULL;
newPtr->rightChild=NULL;
新建PTR->高度=1;
返回newPtr;
}
struct node*rightRotate(struct node*p)//函数右旋转以p为根的树
{
节点*child=p->leftChild;
节点*孙子=子节点->右子节点;
//执行旋转
child->rightChild=p;
p->leftChild=孙子;
//更新节点的高度
p->height=max(高度(p->leftChild),高度(p->righchild))+1;
child->height=max(height(child->leftChild),height(child->rightChild))+1;
//返回新根
返回儿童;
}
struct node*leftRotate(struct node*p)//左旋转以p为根的树的函数
{
节点*child=p->rightChild;
节点*孙子=子节点->左子节点;
//执行旋转
child->leftChild=p;
p->rightChild=孙辈;
//更新高度
p->height=max(高度(p->leftChild),高度(p->righchild))+1;
//返回新根
返回儿童;
}
int getBalance(结构节点*p)
{
if(p==NULL)
返回0;
其他的
返回高度(p->leftChild)-高度(p->rightChild);
}
//BST insert的递归版本,用于在以根为根的子树中插入元素
//返回子树的新根
结构节点*插入(结构节点*&n,int元素)
{
//执行正常的BST插入
if(n==NULL)//如果树为空
返回(newNode(element));
if(元素数据)
{
n->leftChild=insert(n->leftChild,元素);
}
如果(元素>n->数据)
{
n->rightChild=插入(n->rightChild,元素);
}
else//重复节点
{
返回n;
}
//更新此节点的高度
n->height=1+max(高度(n->leftChild)、高度(n->righchild));
//获取平衡因子以查看树是否不平衡
int balance=getBalance(n);
//树是不平衡的,有4种不同类型的旋转
//单次右旋转(左-左案例)
if(余额>1&&elementleftChild->data)
{
返回右旋转(n);
}
//单左旋转(右-右案例)
如果(余额<-1&&element>n->rightChild->数据)
{
返回左旋转(n);
}
//左右旋转
如果(余额>1&&元素>n->leftChild->数据)
{
n->leftChild=leftRotate(n->leftChild);
返回右旋转(n);
}
//左右旋转
if(余额<-1&&elementrightChild->data)
{
n->rightChild=rightRotate(n->rightChild);
返回左旋转(n);
}
cout(右儿童);
}
}
作废打印(结构节点*根)
{

cout我不确定这是您遇到的唯一问题,但这是一个可能导致严重故障的问题:

struct node* newNode(int element) // helper function to return a new node with empty subtrees
{
    node* newPtr = (struct node*) malloc(sizeof(newPtr));
在这里,您分配内存来存放
节点*

您需要的是用于存放
节点的内存

请尝试以下方法:

struct node* newNode(int element) // helper function to return a new node with empty subtrees
{
    node* newPtr = (struct node*) malloc(sizeof(*newPtr));
                                                ^
                                              notice
更新:

在评论中,OP询问:


这确实解决了问题,谢谢!有人能解释一下原因吗

当你这么做的时候:

node* newPtr = (struct node*) malloc(sizeof(newPtr));
这与:

node* newPtr = (struct node*) malloc(sizeof(node*));
因此,您分配了内存来存放指针—可能是8或4个字节

然后,您开始使用以下代码写入内存区域:

newPtr->data = element;
newPtr->leftChild = NULL;
newPtr->rightChild = NULL;
newPtr->height = 1;
这些写入占用的空间超过分配的8(或4)个字节,因此您写入的内存不属于您的程序。这是未定义的行为(即“任何事情都可能发生”),从那里分析出错的原因是没有意义的


但是,很可能内存稍后被覆盖(例如,在第二次
malloc
之后)因此,当你再次读取内存时,你得到的值与最初写的值不同,从那里开始,它就完全错了。< /P>因为这个问题被标记为“代码> C++ +/COD>”,必须返回<代码> MalOC >的返回值。C++中,通常应该使用新的。
newPtr->data = element;
newPtr->leftChild = NULL;
newPtr->rightChild = NULL;
newPtr->height = 1;