0

此方法找到 BST 中的最大节点,返回其值并将其删除。我在 处遇到访问冲突prev->rightLink = cur->leftLink;。我对C++比较陌生,找不到原因。

int CTree::popLargest(TreeNode* tr)
{   
    int largest;
    TreeNode* prev = NULL;
    TreeNode* cur = tr;

    while (cur->rightLink != NULL)
    {
        prev = cur;
        cur = cur->rightLink;
        largest = cur->info;
        //DeleteAttemptTwo(tr, largest);//DeleteItem(largest);     
    }

    if (cur->leftLink != NULL)
    {
        prev->rightLink = cur->leftLink;
    }
    else 
    {
        prev->rightLink = NULL;
    }

    return largest;
}
4

4 回答 4

2

这个 if 和 else 没有什么意义 -

if (cur->leftLink != NULL)
{
    prev->rightLink = cur->leftLink;
}
else 
{
    prev->rightLink = NULL;
}

你想要做的事情可以通过 -prev->rightLink = cur->leftLink;

并且您在此语句上遇到访问冲突的原因是它prev没有指向有效节点,即它是NULL(初始化时)。

于 2012-09-16T04:42:04.250 回答
1

如果树没有任何正确的孩子,prev 将保持为空并在执行时

prev->rightLink = cur->leftLink;

您正在尝试访问空变量的属性,因此是“访问破坏”。

于 2012-09-16T04:45:06.417 回答
1

原因是 prev 仍然为 NULL。当你取消引用它时,你应该验证一个指针是否为NULL。顺便说一句,这个问题很容易通过调试找到。

const int INVALID_VALUE = -1;    // change it by yourself.
int CTree::popLargest(TreeNode* tr)
{  
    int largest = INVALID_VALUE;
    if (tr != NULL)
    {
        TreeNode* prev = NULL;
        TreeNode* cur = tr;
        while (cur->rightLink != NULL)
        {
            prev = cur;
            cur = cur->rightLink;
            largest = cur->info;
            //DeleteAttemptTwo(tr, largest);//DeleteItem(largest);     
        }
        if (prev != NULL)
        {
            if (cur->leftLink != NULL)
            {
                prev->rightLink = cur->leftLink;
            }
            else 
            {
                prev->rightLink = NULL;
            }
        }
    }
    return largest;
}
于 2012-09-16T07:02:00.687 回答
0

您没有考虑tr没有正确元素(tr->rightLink = NULL, cur = tr)的情况,因此while循环的内容永远不会执行。在这种情况下,prev保持为NULL,这意味着您在NULL尝试访问 的rightLink元素时尝试取消引用prev

尝试取消引用NULL将导致某种访问冲突错误。

于 2012-09-16T04:40:57.660 回答