【问题标题】:Binary Search Tree recursive insertion causing stack overflows, iterative insertion not working二叉搜索树递归插入导致堆栈溢出,迭代插入不起作用
【发布时间】:2015-01-05 16:19:54
【问题描述】:

我有这个项目要做,我必须将 10000 个元素(按顺序)添加到二叉搜索树——除其他外,但这不是目前被破坏的。我的递归插入工作正常,直到大约 3500 个元素,然后它中断并导致堆栈溢出。然后我尝试创建代码的迭代版本,但它只添加了元素 9999 和 10000。所以我的问题:

如何使递归插入对大量已排序的元素起作用? 或者我如何让我的迭代插入工作?

我的代码在这里:

递归:

template <typename T>
void BST<T>::insert(BST_Node<T>*& node, const T& data)
{
    if (node == NULL)
    {
        node = new BST_Node<T>(data);
        return;
    }

    if (node->mData == data)
    {
        cout << "Node already exists!" << endl;
        return;
    }

    if (data < node->mData)
        insert(node->mLeft, data);
    else
        insert(node->mRight, data);
}

迭代:

template <typename T>
void BST<T>::insertIterative(BST_Node<T>*& node, const T& data)
{
    if (node == NULL)
    {
        node = new BST_Node<T>(data);
        return;
    }    

    while (node != NULL)
    {
        if (data < node->mData)
        {
            if (node->mLeft == NULL)
            {
            node->mLeft = new BST_Node<T>(data);
            return;
        }
        else
            node = node->mLeft;
    }
    else if (data > node->mData)
    {
        if (node->mRight == NULL)
        {
            node->mRight = new BST_Node<T>(data);
            return;
        }
        else
            node = node->mRight;
    }
}

另外,如有必要,这是我的公共插入功能:

template <typename T>
void BST<T>::insert(T data)
{
    insert(mRootNode, data); //insertIterative(mRootNode, data);
}

最后,这是我在递归代码中断时遇到的错误:

PA7.exe 中 0x7717CF87 (ntdll.dll) 处的未处理异常:0xC00000FD:堆栈溢出(参数:0x00000001、0x006F2FF0)。

我的 BST_Node 构造函数:

template <typename T>
struct BST_Node
{
    T           mData;
    BST_Node<T> *mLeft, *mRight;

    BST_Node();
    BST_Node(T data);
    BST_Node(T data, BST_Node<T> *left, BST_Node<T> *right);
};

template <typename T>
BST_Node<T>::BST_Node()
{
    mData = 0;
    mLeft = NULL;
    mRight = NULL;
}

template <typename T>
BST_Node<T>::BST_Node(T data)
{
    mData = data;
    mLeft = NULL;
    mRight = NULL;
}

template <typename T>
BST_Node<T>::BST_Node(T data, BST_Node<T> *left, BST_Node<T> *right)
{
    mData = data;
    mLeft = left;
    mRight = right;
}

BST 构造函数:

template <typename T>
BST<T>::BST()
{
    mRootNode = NULL;
}

template <typename T>
BST<T>::BST(T data, BST_Node<T> *left, BST_Node<T> *right)
{
    mRootNode->mLeft = left;
    mRootNode->mRight = right;
    mRootNode->mData = data;
}

【问题讨论】:

  • 构造函数的代码是什么?
  • 堆栈溢出最终必然会发生。 @NicolasChabanovsky 非常正确:重新平衡树将有助于避免问题并最大限度地利用堆栈,达到一定的限制。但是,超过该阈值,堆栈将再次变得不足。在某些使用 gcc 作为编译器的系统上,您可能会使用拆分堆栈选项再次提高该阈值。

标签: c++ recursion iteration binary-search-tree


【解决方案1】:

问题可能是因为树不平衡。这意味着在最坏的情况下,调用堆栈将包含与树中项目数相同数量的函数调用。每次插入后,您应该检查树的平衡以及是否有必要进行更正。

您也可以将插入功能划分为:

  1. 找到一个作为父节点的节点
  2. 添加新节点

然后优化查找功能(google "leftmost"/"rightmost")。

【讨论】:

  • 我真希望我能做到。这个项目的重点是将二叉搜索树与 AVL 树进行比较,所以我实际上不应该平衡 BST。我明白这个问题,这意味着你说没有办法解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
相关资源
最近更新 更多