【问题标题】:Inserting into an Array Based Binary Search Tree? C++插入基于数组的二叉搜索树? C++
【发布时间】:2009-11-15 22:20:46
【问题描述】:

我正在尝试插入基于数组的二叉搜索树。

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

我是否将 leftchild 作为 tree[2 * i + 1] 并将 rightchild 作为 tree[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;
}

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

【问题讨论】:

  • 您要达到的实际目标是什么? BST 和数组中的完整二叉树(如在二叉堆中)不能很好地混合,除非您将项目作为一组插入并且不需要增量修改 BST。
  • 我转发了,我认为我现在走上了更好的轨道。谢谢。

标签: c++


【解决方案1】:
  • 先看看什么是 插入 BST 的算法 (不在乎它是怎样的 为数组实现...)
  • 一旦您了解了如何插入,请查看如何选择当前节点的左/右子节点,并将算法替换为您需要访问 基于数组的 BST 中的节点的方式,这意味着您的 ( left,right) --> [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-&gt;keytreeNode-&gt;lefttreeNode-&gt;right 替换为您将如何访问子节点和数组中的值(计算您在数组中存储位置的索引值)。

您可能不需要传递Node*,因为您将在数组上进行操作,并且您可能可以将索引传递给当前node,然后添加到它以获得left/的索引正确的孩子。

顺便说一句(1),如果它是基于 array 的,它可能不应该在内存中增长,你在开始时创建固定大小的数组,它足够大以容纳你的元素,然后你插入将您的元素放入该数组的适当索引中。

顺便说一句 (2),你从哪里得到你想要实现的比较树? Z怎么能在R的左路径上?如果在 R 已经在树中插入 Z 时根据相同的算法插入,则执行 (Z &lt; R ? go left : go right) 所以 Z 最终会从根 R 开始在正确的路径上(与在 R 之后插入第一个 A 时相同:(A &lt; R ? go left : go right)你最终在左边的路径上插入了 A ...)

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

【讨论】:

    【解决方案2】:

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

    显然,您希望将树的根节点放在索引零处。之后,您可以使用下降路径以二进制形式构造一个数字。例如,沿着左-左-右-左向下的树会给你数字 0b1011 = 11。(我用 1 表示左,0 表示右)向其中添加 1,因此该节点将位于索引 12。在树的更远处,使用逻辑或与下降方向。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 采取一个使用指针的实现。在节点结构中使用显式的左/右子树索引,而不是 Node *leftn=n-&gt;left,您将拥有 int leftii=nodes[i].lefti。也就是说,只要传入数组基地址,索引就和指针的意思一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多