当前位置: 首页 > 知识库问答 >
问题:

从BST删除节点时出错

赫连实
2023-03-14

当我通过GPS移除一个节点时,当我试图打印二叉树时,会出现堆栈溢出。下面是我的一些代码。我不能理解它将如何工作良好,如果我删除的名称,但不是,如果我删除的坐标,因为我正在使用相同的删除方法。

我得到的确切错误是“Exe:0xC00000FD中0x013214D6处的未处理异常:堆栈溢出(参数:0x00000001,0x00152FFC)”。在按坐标删除后,在打印函数中会出现这种情况,但如果按名称删除,则不会出现这种情况。

bool BinaryTree::DeleteByName(string city)
{
    if (GetRoot() != NULL)
    {
        return (DeleteByName(GetRoot(), city));
    }
    return false;
}

TreeNode* BinaryTree::DeleteByName(TreeNode *node, string city)
{
    if (node == NULL)
    {
        return node;
    }
    else if (city < node->Data.name)
    {
        node->Left = DeleteByName(node->Left, city);
    }
    else if (city > node->Data.name)
    {
        node->Right = DeleteByName(node->Right, city);
    }
    else
    {
        if (node->Left == NULL && node->Right == NULL)
        {
            delete node;
            node = NULL;
        }
        else if (node->Left == NULL)        
        {
            TreeNode* temp = node;
            node = node->Right;
            delete temp;
        }
        else if (node->Right == NULL)
        {
            TreeNode* temp = node;
            node = node->Left;
            delete temp;
        }
        else
        {
            cout << "Else";
            TreeNode* temp = MinPtr(node->Right);
            node->Data = temp->Data;
            node->Right = DeleteByName(node->Right, temp->Data.name);
        }
    }
    return node;
}

bool BinaryTree::DeleteByCoord(pair<double, double> coords)
{
    if (GetRoot() == NULL)
    {
        return false;
    }
    else
    {
        return DeleteByCoord(GetRoot(), coords);
    }
}

bool BinaryTree::DeleteByCoord(TreeNode* node, pair<double, double> coords)
{
    bool result;

    if (node == NULL)
    {
        return false;
    }
    else
    {
        if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
        {
            return (DeleteByName(node, node->Data.name));           
        }

        result = DeleteByCoord(node->Left, coords);
        if (result == true)
        {
            return result;
        }

        return DeleteByCoord(node->Right, coords);
    }
}




void BinaryTree::Insert(City city)
{
    TreeNode* temp = new TreeNode(city);
    if (GetRoot() == NULL)
    {
        root = temp;
    }
    else
    {
        Insert(temp, GetRoot());
    }
}

void BinaryTree::Insert(TreeNode* toAdd, TreeNode* addHere)
{
    if (toAdd->Data < addHere->Data)
    {
        if (addHere->Left != NULL)
        {
            Insert(toAdd, addHere->Left); 
        }
        else
        {
            addHere->Left = toAdd;
        }
    }
    else if (toAdd->Data > addHere->Data)
    {
        if (addHere->Right != NULL)
        {
            Insert(toAdd, addHere->Right);
        }
        else
        {
            addHere->Right = toAdd;
        }
    }
}

void BinaryTree::InOrderTraversal(TreeNode* node)
{
    if (node != NULL)
    {
        InOrderTraversal(node->Left);
        cout << node->Data << endl;
        InOrderTraversal(node->Right);
    }
}

void BinaryTree::InOrderTraversal()
{
    InOrderTraversal(GetRoot());
}

TreeNode* BinaryTree::GetRoot()
{
    return root;
}

TreeNode* BinaryTree::MinPtr(TreeNode* node)
{
    while (node->Left != NULL)
    {
        node = node->Left;
    }   
    return node;
}

共有1个答案

越安翔
2023-03-14

删除节点时,还需要更新指向已删除节点的父指针。注意这里:

当您直接调用DeleteByName时,它搜索所需节点并返回空指针,该空指针自动设置为父节点指针:

else if (city < node->Data.name)
{
    node->Left = DeleteByName(node->Left, city);
}
else if (city > node->Data.name)
{
    node->Right = DeleteByName(node->Right, city);
}

但从坐标方法调用DeleteByName时,不会重置父级的/指针:

if (node->Data.coordinates.first == coords.first && node->Data.coordinates.second == coords.second)
{
    return (DeleteByName(node, node->Data.name));           
}
else
{
    if (node->Left == NULL && node->Right == NULL)
    {
        delete node;
        node = NULL;
    }
    //... same here
}
    null
 类似资料:
  • 假设我有一个二元搜索树,其中我应该按照标准输入中给定的顺序插入N个唯一编号的键,然后我要删除所有键间隔为I=[最小,最大]的节点,以及与这些节点相邻的所有连接。这给了我很多较小的树,我要以一种特殊的方式将它们合并在一起。更精确地描述问题: 给定包含不同键的BST和间隔I,间隔删除分两个阶段进行。在第一阶段,它将删除关键帧位于I中的所有节点以及与已删除节点相邻的所有边。让生成的图包含k个连通分量T1

  • 我无法从霍夫曼树中正确弹出。现在我正在基于minheap创建霍夫曼树,我想执行以下操作: 如果我们假设A和B是两个不同的子树,我会说如果A的频率小于B的频率,A将首先被弹出。如果他们有相同的频率,那么我会在A的任何叶节点中找到ASCII值中最小的字符。然后我会看看A中最小的字符叶节点是否小于B的任何叶节点。如果是这样,我会在B之前弹出A。如果不是,我会弹出B。 例如: 假设我输入: 进入我的霍夫曼

  • 我想写一个从二叉搜索树中删除节点的方法。 这是我的方法: 问题是它只在某些情况下有效。 假设我输入60,70,65。(根节点为50)树应该看起来像 假设我选择移除60个。一开始这似乎很管用。然而,如果我运行我信任的搜索方法,返回70在任何一个指针上都没有节点。 我假设70被设置为空,然后65才能被提升。由于65在技术上不再与树相连,搜索方法无法找到它。 所以像这样的事情: 问题是,我不明白这是怎么

  • 我很难找出平均和最坏情况下的时间复杂度。因此,我使用以下逻辑删除了BST节点 删除二元搜索树中的节点时,有3种情况 那么,如何计算总体平均时间复杂度和最差时间复杂度??

  •        点击后即可选中要素,在被点中后高亮的要素中点击所要删除的节点即可完成删除。

  • 问题内容: 在使用Jenkins Docker插件时,可能由于错误而导致无法启动群集。我没有注意,目前有数千个脱机节点无法启动。 底线-是否可以批量删除Jenkin中的节点(从属),清理所有脱机节点甚至删除所有节点?重置Jenkins服务器没有帮助,而且我在Jenkins API中找不到方法。 在我开始编写Selenium脚本之类的东西之前,请感谢任何想法。 非常感谢! 问题答案: 该脚本的注释部