C++ 原始二叉树删除与复制问题(改进的解释)
我已经创建了原始二进制树。在此树中,插入与BST不同,它类似于:C++ 原始二叉树删除与复制问题(改进的解释),c++,tree,runtime,binary-tree,C++,Tree,Runtime,Binary Tree,我已经创建了原始二进制树。在此树中,插入与BST不同,它类似于: 如果树为空,则添加值并使其成为根。(假设30) 若树不是空的,则输入父值(30)并向其左子树添加新值(20) 若左子树不为空,则在右子树中插入值(20) 对于下一次插入,再次获取父值以确定要添加值的位置。 &以此类推 它工作正常,除非我试图删除一个有两个子节点的节点。我用来删除的方法是deleteWithCopy 正如我的导师所说,deletewithcopy是: 1.查找要删除的节点(临时)的父节点。 2.如果temp(要删除的
void BinaryTree<mytype>::deletewithTwoChild(BTNode<mytype> *temp)
{
BTNode<mytype> *father = findfather(temp, root); //found address of father of temp node & stored it in pointer
BTNode<mytype> *leaf = temp; //created a copy of temp node
/////CASE 1 (for predecessor)
if(temp==root || father->left==temp) //if temp is left child of its father then
{
leaf = leaf->left; //move leaf 1 time left
while(leaf->right!=0 ) //until leaf reaches the right most node of left subtree
{
leaf = leaf->right; //move leaf 1 time to right
}
//swapping values
mytype var = leaf->key_value; //created a template variable to store leaf's key
leaf->key_value = temp->key_value; //assigning temp's key to leaf
temp->key_value = var; //assigning leaf's key to temp
if(leaf->right!=0) //if leaf has right child then call deletewithOneChild function
{
deletewithOneChild(leaf); //call to respective function
}
else if(leaf->left==0 && leaf->right==0) //if leaf has no children then
{
deleteWithNoChild(leaf); //call to respective function
}
}
/////CASE 2 (for successor)
else if(father->right==temp) //if temp is right child of its father, then
{
leaf = leaf->right; //move leaf 1 time right
while(leaf->left!=0) //until leaf reaches the last node of tree which has no child
{
leaf = leaf->left; //move leaf 1 time to left
}
//swapping values
mytype var = leaf->key_value; //created a template variable to store leaf's key
leaf->key_value = temp->key_value; //assigning temp's key to leaf
temp->key_value = var; //assigning leaf's key to temp
if(leaf->right!=0) //if leaf has right child then call deletewithOneChild function
{
deletewithOneChild(leaf); //call to respective function
}
else if(leaf->left==0 && leaf->right==0) //if leaf has no children then
{
deleteWithNoChild(leaf); //call to respective function
}
}
当运行时错误弹出时,我试图删除节点80、60、120、140。Plz帮助:((我还需要指南)如何处理树iff 30被删除。正如我所知,后继和前置的定义是不同的 后继者:右子树的最小节点,即右子树的最左侧节点。 前置:左子树的最大节点,即左子树的最右节点 回到问题1。在案例1中交换值后,我注意到了
if else
的情况。因为在案例1中,您找到了子树最右边的节点,叶->右
始终为空
,叶->左
可能不是空
。因此,无法调用任何删除函数在交换值后,在case中会出现异常。这将导致错误的BST问题,甚至更糟的是,程序崩溃。因此,case中的if-else
条件为:
// leaf->right always be null, only need to verify leaf->left.
if (leaf->left != 0)
{
deleteWithOneNode(leaf);
}
else
{
deleteWithNoChild(leaf);
}
void BinaryTree<myType>::delete(BTNode<myType>* node, BTNode<myType>* parent)
{
if (node->right) // find successor first
{
BTNode* ptrParent = node;
BTNode* ptr = node->right;
while (ptr->left)
{
ptrParnet = ptr;
ptr = ptr->left;
}
// Since the ptr will be delete, we only assign the value of ptr to the value node
node->key_value = ptr->key_value;
if (node == ptrParent)
{
ptrParnet->right = ptr->right;
}
else
{
ptrParent->left = ptr->right;
}
delete ptr;
}
else if (node->left) // find predecessor
{
BTNode* ptrParent = node;
BTNode* ptr = node->left;
while (ptr->right)
{
ptrParent = ptr;
ptr = ptr->right;
}
// Since the ptr will be delete, we only assign the value of ptr to the value node
node->key_value = ptr->key_value;
if (node == ptrParent)
{
ptrParent->left = ptr->left;
}
else
{
ptrParent->right = ptr->left;
}
delete ptr;
}
else
{
if (node->key_value > parent->key_value)
{
parent->right = NULL;
}
else
{
parent->left = NULL;
}
delete node;
}
}
问题2。据我所知,BST中删除一个节点没有选择前置节点或后续节点的规则,删除节点的父(父)节点仅在交换整个节点时使用,而不是仅交换节点的值。因此,我的删除功能是:
// leaf->right always be null, only need to verify leaf->left.
if (leaf->left != 0)
{
deleteWithOneNode(leaf);
}
else
{
deleteWithNoChild(leaf);
}
void BinaryTree<myType>::delete(BTNode<myType>* node, BTNode<myType>* parent)
{
if (node->right) // find successor first
{
BTNode* ptrParent = node;
BTNode* ptr = node->right;
while (ptr->left)
{
ptrParnet = ptr;
ptr = ptr->left;
}
// Since the ptr will be delete, we only assign the value of ptr to the value node
node->key_value = ptr->key_value;
if (node == ptrParent)
{
ptrParnet->right = ptr->right;
}
else
{
ptrParent->left = ptr->right;
}
delete ptr;
}
else if (node->left) // find predecessor
{
BTNode* ptrParent = node;
BTNode* ptr = node->left;
while (ptr->right)
{
ptrParent = ptr;
ptr = ptr->right;
}
// Since the ptr will be delete, we only assign the value of ptr to the value node
node->key_value = ptr->key_value;
if (node == ptrParent)
{
ptrParent->left = ptr->left;
}
else
{
ptrParent->right = ptr->left;
}
delete ptr;
}
else
{
if (node->key_value > parent->key_value)
{
parent->right = NULL;
}
else
{
parent->left = NULL;
}
delete node;
}
}
在调试器中运行该程序。它将告诉您崩溃发生的位置,向您显示函数调用堆栈,让您看到崩溃是如何发生的,并让您检查变量以帮助您理解崩溃的原因。@JoachimPileborg I have,&它在访问临时节点(其值在交换后被删除)时显示错误。