C++ 二叉搜索树中拒绝删除的节点
我目前正在编写一个程序,该程序将从二叉搜索树中删除一个节点(除其他外,删除是我的问题),我在删除的最后一步遇到了问题,特别是删除一个有两个子节点的节点的最后一步 我删除的方式与描述的方式相同。 我取左下最远的子节点(如果在根的右侧)或右下最远的子节点(如果在左侧),并用该值替换要删除的节点的值,然后删除刚从中复制的节点 除了删除从中复制的节点外,我已完成所有步骤;由于某些原因,我的代码没有正确地删除它,并为我刚刚尝试删除的节点创建了一个随机数值和一个随机父值。我相信这是由树中某个地方的未修复链接造成的,但作为一个没有经验的程序员,我找不到它。希望有更精通BST的人能帮助我 这是我的代码(我只包含了影响删除功能的代码,我认为没有必要包含后面的内容,例如销毁功能):C++ 二叉搜索树中拒绝删除的节点,c++,binary-search-tree,C++,Binary Search Tree,我目前正在编写一个程序,该程序将从二叉搜索树中删除一个节点(除其他外,删除是我的问题),我在删除的最后一步遇到了问题,特别是删除一个有两个子节点的节点的最后一步 我删除的方式与描述的方式相同。 我取左下最远的子节点(如果在根的右侧)或右下最远的子节点(如果在左侧),并用该值替换要删除的节点的值,然后删除刚从中复制的节点 除了删除从中复制的节点外,我已完成所有步骤;由于某些原因,我的代码没有正确地删除它,并为我刚刚尝试删除的节点创建了一个随机数值和一个随机父值。我相信这是由树中某个地方的未修复链接
#包括
使用名称空间std;
结构节点
{
int data;//在树指针中存储数据
node*parent;//用于在树中向上移动
node*left;//用于在树中向左移动
node*right;//用于在树中向右移动
};
节点*创建(int数据,节点**树)//函数将元素插入到树中
无效打印树(节点*树)//函数打印树
节点*搜索(int键,节点*树)//函数在树中查找数据
节点*delNode(节点*树,节点*根)//函数从树中删除数据
节点*FindSalestRight(节点*树,节点**最小);
节点*FindLargesLeft(节点*树,节点**最小);
int main()
{
node*root=NULL;//root将是树中的第一个元素
node*current=NULL;//为insert函数返回值以保留更改
int value;//用户输入的值
while(true)//循环使用数据填充树
{
库特值;
if(value==0)//在将0输入到树中之前,在输入0时退出
打破
current=create(value,&root);//将值插入到树中
cout parent!=NULL)//如果树值不是root,则分配一个父级(root的父级为NULL,因此分配将崩溃)
{
父=树->父;
}
节点*curr=树;
//正在删除右侧有2个子节点的节点
//也会有无子女、1名子女和左侧2名子女的情况,但我没有将其包括在内,因为前两名子女已经完成,解决后一名子女可以复制:)
如果(树->左!=NULL&&tree->右!=NULL&&parent->右==tree&&parent!=NULL)
{
node*minimate;//在左侧查找最小数据值的节点
//初始化并使其指向零
最小=新节点;
最小->左=空;
最小->右=空;
最小->父级=NULL;
node*nReplace=NULL;//替换树中数据的节点
//初始化并使其指向零
nReplace=新节点;
nReplace->left=NULL;
nReplace->right=NULL;
nReplace->parent=NULL;
nReplace=findsmalestright(tree,&minimable);//用于在右侧查找最小数据值的函数
tree->data=nReplace->data;//用新数据替换树的数据
cout我认为您的findSalestRight()从递归到返回值都是一团糟
你只需要在右子树上找到最小的元素,也就是说,对于右子树,继续迭代它的左子树,直到最后一个,这是最小的一个
代码如下所示:简单如下:(首先查看图片了解名称关联)
if(current->left!=NULL&¤t->right!=NULL)//当前节点(要删除)是否有2个子节点的条件
{if((当前->右侧)->左侧!=NULL)//如果右侧子项具有左侧子项,则转到最后一个最左侧子项。
{
节点*左电流;
节点*leftCurrentPred;
leftCurrentPred=当前->右侧;
leftCurrent=(当前->右)->左;
while(leftCurrent->left!=NULL)
{
leftCurrentPred=leftCurrent;
leftCurrent=leftCurrent->left;
}
当前->数据=左当前->数据;
delNode(leftCurrent,root);//删除leftCurrent节点,即没有子节点的节点
leftCurrentPred->left=NULL;
但是作为一个没有经验的程序员,我找不到它。好吧,你写了一个程序,所以你现在是一个有经验的程序员。底线是,如果你有写程序的知识,那么你必须有调试程序的知识。你在某个地方写了一些计划,根据这个计划,你写了一个C++程序。如果程序没有按预期执行,则使用调试器并逐步执行程序,以查看程序与计划的偏离。
#include <iostream>
using namespace std;
struct node
{
int data; //Stores data within the trees pointers
node * parent; //Used to move up in the tree
node * left; //Used to move left in the tree
node * right; //Used to move right in the tree
};
node * create (int data, node **tree); //Function to insert elements into the tree
void printTree (node * tree); //Function to print the tree
node *search(int key, node *tree); //Function to find data in the tree
node * delNode (node * tree, node * root); //Function to delete data from the tree
node * findSmallestRight (node * tree, node **smallest);
node * findLargestLeft (node * tree, node **smallest);
int main()
{
node * root = NULL; //Root will be the first element in the tree
node * current = NULL; //Return value for insert function to keep changes
int value; //Value entered by user
while (true) //Loop to fill tree with data
{
cout << "Enter an integer, 0 to quit" << endl;
cin >> value;
if (value == 0) //Quit when 0 is entered, BEFORE entering it into the tree
break;
current = create(value, &root); //Insert value into the tree
cout << "After inserting " << value << " tree is:" << endl;
printTree(root); //Print the tree
}
while (true) //Loop to delete data from tree
{
cout << "Search for a value to delete from the tree, 0 to quit" << endl;
cin >> value;
if (value == 0)
break;
current = search(value, root); //Find the value in the tree
if (current == NULL)
cout << value << " is not in tree. Could not delete." << endl;
else
{
root = delNode(current, root); //Delete the data
cout << value << " has been deleted. The tree is now:" << endl;
printTree(root); //print the tree
}
}
destroy(root); //Destroy the tree
return 0;
}
void printNode (node * Node) //Function to print a node in the tree
{
cout << "addr= " << Node << " parent= " << Node->parent << " left= " << Node->left << " right= " << Node->right << " data= " << Node->data << endl;
}
node * createNode (int data) //Function to create a new node in the tree
{
node * newNode = NULL; //Create a new pointer
newNode = new node; //Make that pointer a node
newNode->data = data; //Fill it with data
newNode->left = NULL; //Make it point left to NULL
newNode->right = NULL; //and right to NULL
return newNode;
}
node * create (int data, node **tree) //Function to insert elements into the tree
{
node * newNode = NULL; //Create a new pointer
if ((*tree) == NULL) //Check if tree exists already
{
//If it doesn't, create a new node and make it the root
newNode = createNode(data);
*tree = newNode;
(*tree)->parent = NULL; //Root has a parent of NULL
}
else if (data < (*tree)->data) //If the data is smaller than root, insert on the left
{
if ((*tree)->left == NULL)//If there is no node on the left, create a new one and point to it
{
newNode = createNode(data);
(*tree)->left = newNode;
newNode->parent = *tree;
}
else
{
newNode = create(data, &((*tree)->left));//If there is a node on the left, repeat function until there isn't
}
}
else //If the data is greater than or equal to root, insert on the right
{
if ((*tree)->right == NULL)
{
newNode = createNode (data); //If there is no node on the right, create a new one and point to it
(*tree)->right = newNode;
newNode->parent = *tree;
}
else
{
newNode = create(data, &((*tree)->right)); //If there is a node on the right, repeat function until there isn't
}
}
return newNode; //Return the new node to keep the changes to the value
}
void printTree (node * tree) //Function to print the tree
{
if (tree != NULL) //Check if tree actually existsreturn root;
{
//Recursively print the left side, then the root, then the right side
printTree(tree->left);
printNode(tree);
printTree(tree->right);
}
}
node *search(int key, node *tree) //Function to find data in the tree
{
if (tree == NULL || tree -> data == key)
{
return tree; //If the data either does not exist or has been found, return
}
if (key < tree->data)
{
return search(key, tree->left); //If the data is less than the current data, keep checking the left
}
else
{
return search(key, tree->right); //If the data is more than the current data, keep checking the right
}
}
node * delNode (node * tree, node * root)
{
node * parent; //Node for quick-reference and manipulation of tree's parent
if (tree->parent != NULL) //If tree value is not root assign a parent (root has parent of NULL so assigning would crash)
{
parent = tree->parent;
}
node * curr = tree;
//Removing node with 2 children on right
//There would also be cases for no children, 1 child, and 2 children on left but I did not include them as the two former are done and the latter can be copied once this is solved :)
else if (tree->left != NULL && tree->right != NULL && parent->right == tree && parent != NULL)
{
node * smallest; //Node to find smallest data value on left side
//Initialise and make it point to nothing
smallest = new node;
smallest->left = NULL;
smallest->right = NULL;
smallest->parent = NULL;
node * nReplace = NULL; //Node to replace data in tree
//Initialise and make it point to nothing
nReplace = new node;
nReplace->left = NULL;
nReplace->right = NULL;
nReplace->parent = NULL;
nReplace = findSmallestRight(tree, &smallest); //Function to find smallest data value on right side
tree->data = nReplace->data; //Replace tree's data with the new data
cout << nReplace << " " << nReplace->data << endl; //Debugging code
delete nReplace; //Delete nReplace
cout << nReplace << " " << nReplace->data << endl; //Debugging code
}
return root; //Return root to keep changes in tree
}
node * findSmallestRight (node * tree, node **smallest) //Function to find smallest data value on right side
{
node * parent = tree->parent; //Node for easy manipulation of tree's parent
//Check if current value is a potential candidate for smallest
if (tree->left == NULL && tree->right == NULL && parent->left == tree)
{
*smallest = tree; //If it is, make smallest equal to it
}
if (tree->left == NULL && tree->right != NULL) //Check if the are only branches on the right
{
findSmallestRight (tree->right, smallest); //Recurse through the right
}
else if (tree->left != NULL && tree->right == NULL) //Check if there are only branches on the left
{
findSmallestRight (tree->left, smallest); //Recurse through the left
}
else if (tree->left == NULL && tree->right == NULL) //Check if there are no branches on both sides
{
return *smallest; //Return the smallest
}
else
{
//If there are branches on both sides recurse through both
findSmallestRight (tree->left, smallest);
findSmallestRight (tree->right, smallest);
}
return *smallest; //Return the smallest
}
if (current->left != NULL && current->right != NULL) //condition if you Current Node (to be deleted) has 2 Children
{ if((current->right)->left!=NULL) //If Right Child has left child go till last leftmost child.
{
Node* leftCurrent;
Node* leftCurrentPred;
leftCurrentPred=current->right;
leftCurrent=(current->right)->left;
while(leftCurrent->left != NULL)
{
leftCurrentPred=leftCurrent;
leftCurrent=leftCurrent->left;
}
current->data=leftCurrent->data;
delNode(leftCurrent, root); //Delete leftCurrent node i.e node with no child
leftCurrentPred->left=NULL;
cout<<item<<" has been removed from the Tree."<<endl;
}
else
{ //If Right Child of current doesn't has Left child it is itself smallest one.
Node* temp=current->right;
current->data=temp->data;
current->right=temp->right;
delNode(temp,root); //Delete temp node i.e node with no child
cout<<item<<" has been removed from the Tree."<<endl;
}
}