插入基于数组的二进制搜索树? C ++

时间:2009-11-15 22:20:46

标签: c++

我试图插入基于数组的二进制搜索树。

我不确定如何防止使用左右索引覆盖数据......

我是否将leftchild插入树[2 * i + 1]并将右侧子插入树[2 * i + 2]?我认为这是为了找到一个节点的名称......

这就是我的问题。不知道如何插入,递归或迭代(我已经递归选择,但可能完全错误)。

BST::BST(int capacity) : items(new item[capacity]), size(0),
leftChild(0), rightChild(0), root_index(1)
{
 items->empty = true;
 maxSize = capacity-1;
}

以下是插入功能。我见过许多处理链接列表实现,但没有基于数组的!这是我的尝试:

void BST::insert(const data& aData)
{
if ( items[root_index].empty ) 
{
    items[root_index].theData = aData;// Get the data.
    items[root_index].empty = false;
    oldRoot.theData = aData;
} 
else  
{   
    if ( aData < items[root_index].theData )
    {
        leftChild = root_index * 2;
        if ( items[leftChild].empty )
        {
            items[leftChild].theData = aData;
            items[leftChild].empty = false;
        }//items->empty = true;
        else 
        {
            items[root_index].theData = items[leftChild].theData;
            this->insert(aData);
        }
    }
    else if ( items[root_index].theData < aData )
    {
        rightChild = root_index * 2 + 1;
        if ( items[rightChild].empty )
        {
            items[rightChild].theData = aData;
            items[rightChild].empty = false;
        }
        else//items->empty = true;
        {
            items[root_index].theData = items[rightChild].theData;      
            this->insert(aData);
        }

    }
    else return;
}
items[1].theData = oldRoot.theData;
}

什么是正确的?...有没有人有任何基于数组的插入插入?我似乎陷入无限递归

3 个答案:

答案 0 :(得分:2)

  • 首先来看看是什么 插入BST的算法 (不关心它是怎么回事 为数组实现...)
  • 一旦了解了如何插入,请查看如何选择当前节点的左/右子节点,并使用您在基于阵列的BST 中访问节点所需的方式替换算法,这意味着您的(左,右) - &gt; [2 * i + 1],[2 * i + 2] ...此计算为您提供阵列中节点的位置

查看wikipedia处的BST说明以及以下示例:

 /* Inserts the node pointed to by newNode into the subtree rooted at treeNode */
 void InsertNode(Node* &treeNode, Node *newNode)
 {
     if (treeNode == NULL)
       treeNode = newNode;
     else if (newNode->key < treeNode->key)
       InsertNode(treeNode->left, newNode);
     else
       InsertNode(treeNode->right, newNode);
 }

替换在数组中访问节点和值的方式,意味着将treeNode->keytreeNode->lefttreeNode->right替换为访问子节点的方式和数组中的值(计算索引的值)在数组中存储值的位置。)

您可能不需要传递Node*,因为您将在数组上运行,并且可能您可以将索引传递给当前node,然后只需添加它以获取左/右孩子的指数。

Btw(1),如果是数组,它可能不应该在内存中增长,你在开头创建固定大小的数组,它足够大,可以容纳你的元素然后你插入您的元素到该数组的适当索引中。

Btw(2),你在哪里得到了你想要实现的比较树? Z怎么能从R的左边路径?如果在R已经在树中时插入Z时按照相同的算法插入,则执行(Z < R ? go left : go right),因此Z将从根R开始在右路径上(与在R之后插入第一个A时相同:{ {1}}您最终在左侧路径上插入了A ...)

顺便说一句(3),正如其他人提到的那样,最终的树依赖于插入的顺序。生成树的最低效方法是对元素进行排序并逐个插入,因为最终会得到链表,因此遍历将采用O(n)而不是O(logN)。因此,如果您有固定的元素集,则可以选择随机或一致的中间元素。

答案 1 :(得分:1)

然后,我认为你希望能够在插入新元素时使用数组中的元素而不必重新排列数组?

显然,您希望将树的根节点放在索引零处。之后,您可以使用下降路径来构造二进制数。例如,向左下左下方的树将给出数字0b1011 = 11.(我用左边的1和右边的0)添加1到那个,所以这个节点将在索引12处。进一步在树中,使用逻辑或下降方向。

答案 2 :(得分:1)

如果要在数组中布置完整的二叉树,i_left=i_parent*2i_right=i_parent*2+1效果很好(i_root=1)。通过仅修改沿树的根路径到另一个节点的节点,可以有效地更新BST;与位置无关的显式左,右子指针(或索引)允许这样做,因为移动子树的位置(或重用)不需要深层复制。

如果集合是固定的,那么有一个打包的二进制搜索树(基于父索引的左右子树的固定位置,如上所述)是唯一有意义的方法。对它进行排序并递归,抓住已排序子范围的中间部分并将其用作BST子树的根。