我预先编写的代码是我试图解决的问题:
int maxExtract(node **tree)
{
node *prev = NULL;
node *curr = *tree;
int ret;
if(curr == NULL)
{
printf("Tree is empty!\n");
exit(-1);
}
while( curr->right != NULL )
{
prev = curr;
curr = curr->right;
}
ret = curr->data;
if( prev != NULL )
prev->right = curr->left;
else if( curr == *tree )
*tree = curr->left;
free(curr);
return ret;
}
我了解除else if (curr == *tree)
条件以外的所有内容。我认为如果最大节点最终成为根节点。但是,您是否需要更改连接之后的连接,如果在提取旧树之后将树的右侧和左侧连接到此新根?
答案 0 :(得分:3)
我认为如果最大节点最终成为根。
那是完全它意味着什么,如果是这样的话,那么该节点右侧可能只有 nothing ,因为如果有,那么最大值会在那个(右)子树的某个地方,而不是在根。
因此,让我们考虑根 最大的树(A1/A2
是任意子树,包括空子树):
MAX
/
x
/ \
A1 A2
要提取最大值,您想要留下的只是:
x
/ \
A1 A2
因此,您要执行的操作是使x
成为树的新根 - 这是通过代码中的行完成的:
*tree = curr->left;
我可能会稍微改写一下,以明确处理不同的情况,而不是依赖于发生或不发生的事情,具体取决于代码中间的各种决策。我的意思是:
int maxExtract (node **tree) {
// Handle empty tree as error.
if (*tree == NULL) {
printf ("Tree is empty!\n");
exit (-1);
}
// Handle root is max, i.e., has no right subtree.
if ((*tree)->right == NULL) {
node *nodeToDelete = *tree; // Save root for deletion.
int retVal = nodeToDelete->data; // Get data to return.
*tree = nodeToDelete->left; // Set new root.
free (nodeToDelete); // Delete old root.
return retVal; // Return old root value.
}
// Locate max and its previous.
node *prev = *tree;
node *curr = (*tree)->right;
while (curr->right != NULL) {
prev = curr;
curr = curr->right;
}
// Max has no right sub-tree but it MAY have a left one
// which needs to be transferred as-is to the right of prev.
int retVal = curr->data; // Get data to return.
node *nodeToDelete = curr; // Save root for deletion.
prev->right = curr->left; // Transfer left sub-tree (or null).
free (nodeToDelete); // Delete old max.
return retVal; // Return old max value.