二叉搜索树removeNode的实现
Implementation of removeNode for a Binary Search Tree
我正在尝试在一个程序中实现一本教科书中讨论的二叉搜索树的删除算法,但是这本书对所描述的一些函数的细节很少,所以我已经猜到了它们的含义并实现了它指定的函数和我自己的一些函数。我遇到的问题是removeNode
函数处理0-1-2个孩子的情况。
书中为removeNode
指定了以下伪代码
removeNode(N: BinaryNode)
{
if(N is a leaf)
Remove N from the tree
else if (N has only one child C)
{
if(N was a left child of its parent P)
Make C the left child of P
else
Make C the right child of P
}
else //Node has two children
{
//Find S, the node that contains N's inorder successor
//Copy the item from node S into node N
//Remove S from the tree by using the previous
//technique for a leaf or a node with one child
}
在这个函数中,如何使C成为p 的子元素?给定一个节点,没有指向父节点的任何东西你怎么做才能找出树的父节点是谁?通常你需要一个跟踪节点来跟踪,但由于书的"最终草案",我怀疑这不是他们所暗示的。
"最终稿"
removeNode(nodePtr: BinaryNodePointer): BinaryNodePointer
{
if(N is a leaf)
{
//Remove leaf from the tree
delete nodePtr
nodePtr = nullPtr
return nodePtr
}
else if (N has only one child C)
{
if(N was a left child of its parent P)
nodeToConnectPtr = nodePtr->getleftChildPtr() //<---I assume this means nodePtr->left
else
nodeToConnectPtr = nodePtr->getRightChildPtr() //<--nodePtr->right?
delete nodePtr
nodePtr = nullptr
return nodeToConnectPtr
}
else //Node has two children
{
//Find the inorder succesor of the entry in N: it is in the left subtree rooted
//at N's Child
tempPtr = removeLeftMosstNode(nodePtr->getRightChild(), newNodeValue)
nodePtr->setRightChildPtr(tempPtr) //<--nodePtr->right = tempPtr?
nodePtr->setItem(newNodeValue) // nodePtr->vendorData = newNodeValue?
return nodePtr
}
这是我基于上述设计提出的实现。我知道有些零件出了问题,但我不知道还能做些什么来修理它们。谁能建议解决儿童案件和任何其他问题,我可能错过了?
My Implementation
aBst::treeNode * aBst::removeNode(aBst::treeNode * nodePtr)
{
//This functions deletes a node and then returns the pointer to the child to take the place of deleted child
aVendor * tempVendorPtr;
treeNode * nodeToConnectPtr, *tempPtr;
//The node passed is the node that needs to be removed
if (nodePtr->right == NULL && nodePtr->left == NULL) //----No Child----
{
delete nodePtr;
nodePtr = NULL;
return nodePtr;
}
else if ((nodePtr->right != NULL) != (nodePtr->left != NULL))//----One Child----
{
if (nodePtr->left != NULL)//left child
{
nodeToConnectPtr = nodePtr->left; //Wrong
}
else if (nodePtr->right != NULL) //right child
{
nodeToConnectPtr = nodePtr->right; //Wrong
}
delete nodePtr;
nodePtr = NULL;
return nodeToConnectPtr;
}
else //-----Two Child-----
{
//find minimum value of right subtree, stores the pointer to the vendorData it carries through the parameter and calls removeNode
tempPtr = removeLeftMostNode(nodePtr->right, tempVendorPtr);
nodePtr->vendorData = tempVendorPtr;
nodePtr->right = tempPtr;
return nodePtr;
}
}
所有功能int aBst::countKids(aBst::treeNode * subTreePtr)
{
if (subTreePtr == NULL) //Empty Tree
{
return -1;
}
else if (subTreePtr->right == NULL && subTreePtr->left == NULL) //----No Child----
{
return 0;
}
else if ((subTreePtr->right != NULL) != (subTreePtr->left != NULL))//----One Child----
{
return 1;
}
else if ((subTreePtr->right != NULL) && (subTreePtr->left != NULL))//----Two Child----
{
return 2;
}
//Something unexpected occurred
return -1;
}
bool aBst::remove(char nameOfVendor[])
{
bool failControl = false;
removeValue(root, nameOfVendor, failControl);
return failControl;
}
aBst::treeNode * aBst::removeValue(aBst::treeNode * subTreePtr, char nameOfVendor[], bool& success)
{
//Note: the subTreePtr should be root in initial call
treeNode * tmpPtr;
char name[MAX_CHAR_LENGTH];
//Make sure passed success bit is false
success = false;
subTreePtr->vendorData->getName(name);
if (subTreePtr == NULL) //Empty Tree
{
success = false;
return NULL;
}
else if (strcmp(name, nameOfVendor) == 0) //Evaluates to true if there is a match
{
subTreePtr = removeNode(subTreePtr);
success = true;
return subTreePtr;
}
else if (strcmp(name, nameOfVendor) > 0) // Go left
{
//Protects algorithm from bad data crash
if (subTreePtr->left == NULL)
{
return subTreePtr;
}
tmpPtr = removeValue(subTreePtr->left, nameOfVendor, success);
subTreePtr->left = tmpPtr;
return subTreePtr;
}
else // Go Right
{
//Protects algorithm from bad data crash
if (subTreePtr->right == NULL)
{
return subTreePtr;
}
tmpPtr = removeValue(subTreePtr->right, nameOfVendor, success);
subTreePtr->right = tmpPtr;
return subTreePtr;
}
//For loop was broken and function returns false
return subTreePtr;
}
aBst::treeNode * aBst::removeNode(aBst::treeNode * nodePtr)
{
aVendor * tempVendorPtr;
treeNode * nodeToConnectPtr, *tempPtr;
//The node passed is the node that needs to be removed
if (nodePtr->right == NULL && nodePtr->left == NULL) //----No Child----
{
delete nodePtr;
nodePtr = NULL;
return nodePtr;
}
else if ((nodePtr->right != NULL) != (nodePtr->left != NULL))//----One Child----
{
if (nodePtr->left != NULL)//left child
{
nodeToConnectPtr = nodePtr->left;
}
else if (nodePtr->right != NULL) //right child
{
nodeToConnectPtr = nodePtr->right;
}
delete nodePtr;
cout << "calledn";
nodePtr = NULL;
return nodeToConnectPtr;
}
else //-----Two Child-----
{
//find minimum value of right subtree, stores the pointer to the vendorData it carries through the parameter and calls removeNode
tempPtr = removeLeftMostNode(nodePtr->right, tempVendorPtr);
nodePtr->vendorData = tempVendorPtr;
nodePtr->right = tempPtr;
cout << "nleaving Two Childn";
return nodePtr;
}
}
aBst::treeNode * aBst::removeLeftMostNode(aBst::treeNode * nodePtr, aVendor*& vendorDataRef)
{
if (nodePtr->left == NULL)
{
//Target acquired
vendorDataRef = nodePtr->vendorData;
return removeNode(nodePtr);
}
else
return removeLeftMostNode(nodePtr->left, vendorDataRef);
}
我想你和我有类似的问题。当只有一个子节点时,你所做的,就是分别将指针指向右或左分支。但是你需要用那个子树中的一个节点来替换这个节点。这可以通过在左子树中搜索最小节点并用这个最小节点替换您想要删除的节点来完成。然后需要删除刚刚插入的节点,以防止节点复制。这就是理论。我还没有设法实现正确的自己。
我又把链接删除了。我发现在回答问题时问问题被认为是不礼貌的。相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 二叉搜索树removeNode的实现