我正在尝试编写一个从二叉树中删除节点的函数。我还没有对该函数进行编码,我正在尝试考虑删除节点时应考虑的不同条件。我猜可能的条件是:
该节点没有子节目
该节点有一个孩子
该节点有2个孩子
在每种情况下,执行删除功能的算法是什么?
答案 0 :(得分:5)
这是你在任何关于算法的标准教科书中都能找到的东西,但是我们假设你对不平衡的情况感兴趣(平衡树通常在删除后执行一些称为“旋转”的重新平衡操作)并使用“明显的”数据结构(保持值的tree_node
结构和指向其他tree_node
的两个指针):
NULL
; O(tree_height) = O(n)
,但它不是问题(至少在理论上),因为这将无法找到节点的复杂性。答案 1 :(得分:1)
您的树有任何其他属性吗? 它是AVL吗?
如果没有,有一些非常明显和直接的方法可以做你想做的事情(这将取决于你的数据表示,正如Vitalij所说)。
如果它是一个AVL,例如,也有一些众所周知的方法(维基百科将告诉你更多关于该主题)
答案 2 :(得分:1)
首要任务是查找是否存在将在搜索期间完成的节点,其余条件是正确的。
Leaf node:将父级的子项(右/左)设置为NULL。
有一个孩子:只需将要删除的节点的子节点设置为其父节点的子节点。
有两个孩子:基本上必须通过修剪子树来重新排序整个子树,方法是找到要删除的节点的新子节点。
答案 3 :(得分:1)
假设您正在处理常规二叉树,请执行以下操作,
节点没有子节点 - 即它是一片叶子:方便地删除它..
节点有一个子节点 - 使节点的父节点被删除其子节点的父节点,然后删除该节点。即,如果必须删除A->Parent = B; C->Parent = A;
和A
,则1.制作C->Parent = B
; 2.删除A
;
棘手的......是的,将正确子树工作中最左边的子项删除的节点替换为左子树的最右边的树,要么会...因为它可以...可以这样看,
删除节点时,必须用满足某些属性的节点替换它... 假设我们的二叉树在顺序遍历中表示已排序的数字(按递增顺序),则删除的节点应替换为其子树中的某个节点。它应该比整个剩余的左子树更大,并且小于整个剩余的右子树(剩余意味着在成功调整删除的节点后剩余的子树)。只存在两个这样的节点,右子树的最左边的叶子,或者左边的最右边的节点。
因此,从任何一个替换已删除的节点就足够了...... !!
答案 4 :(得分:0)
从二进制搜索树中一次删除给定的键。可能的相等键已插入到现有节点的左分支中。请注意,插入策略还会影响删除的方式
BinarySearchTree-Delete
Node Delete(Node root, Key k)
1 if (root == null) // failed search
2 return null;
3 if (k == root.key) // successful search
4 return DeleteThis(root);
5 if (k < root.key) // k in the left branch
6 root.left = Delete(root.left, k);
7 else // k > root.key, i.e., k in the right branch
8 root.right = Delete(root.right, k);
9 return root;
Node DeleteThis(Node root)
1 if root has two children
2 p = Largest(root.left); // replace root with its immediate predecessor p
3 root.key = p.key;
4 root.left = Delete(root.left, p)
5 return root;
6 if root has only left child
7 return root.left
8 if root has only right child
9 return root.right
10 else root has no children
11 return null
Node Largest(Node root)
1 if root has no right child
2 return root
3 return Largest(root.right)