使用inorder二叉树实现的列表

时间:2009-10-31 17:03:59

标签: python algorithm binary-tree

对于新的计算机科学任务,我们将使用inorder二叉树实现列表/数组。我想要一个建议而不是一个解决方案。

这个想法是拥有一个二进制树,它的节点可以通过索引访问,例如

t = ListTree()
t.insert(2,0) # 1st argument is the value, 2nd the index to insert at
t.get(0) # returns 2

存储值的Node类不可修改,但有一个属性size,其中包含下面的子项总数,以及leftright和{{1指向子节点并相应地存储值。

我目前的主要问题是跟踪索引 - 因为我们不允许在节点本身存储节点的索引,所以我必须依靠遍历来跟踪它。因为我总是在遍历时从左侧节点开始,我还没有想过以递归方式找出我们当前所处的索引的方法。

欢迎任何建议。

谢谢!

5 个答案:

答案 0 :(得分:1)

您真的不希望将它存储在节点本身上,因为必须在索引小于插入索引的所有节点的插入上更新索引。我认为真正的问题是如何进行有序遍历。尝试使用递归函数返回其左侧的节点数。

答案 1 :(得分:1)

我认为您不想存储索引,而只是存储每个子树的大小。对于insance,如果你想查找列表中的第10个元素,并且左右子树各有7个元素,你会知道根是8个元素(因为它是按顺序的二进制),并且第一个元素右子树的第9个。有了这些知识,你就会进入正确的子树,寻找第二个元素。

HTH

答案 2 :(得分:0)

嗯,二叉树中的节点不能有值和索引。它们可以有多个数据,但树只能在一个数据上键入/构建。

也许你的作业希望你使用索引值作为树的键,并将值附加到节点,以便快速检索给定索引的值。

答案 3 :(得分:0)

树必须平衡吗?算法是否需要高效?

如果没有,那么最简单的方法就是创建一个所有左子节点都为空的树,即一个转换为链表的树。

要插入,递归查看转到右边的子节点,然后在返回的路上更新节点的大小。像(伪代码)

的东西
function insert(node, value, index, depth)
    if depth < index
        create the rightchild if necessary
        insert( rightchild, value, index, depth + 1)
    if depth == size
        node.value = value
    node.size = rightchild.size + 1

完成此操作后,您可以将其修改为更加平衡。当增加列表的长度时,根据当前具有最少的节点将节点添加到左子节点或右子节点,并在离开递归的路径上更新大小。

要概括为更高效,您需要根据其二进制表示法处理索引。

例如,空列表有一个节点,没有值为null且大小为0的子节点。

假设您要在索引1034处插入“hello”。然后您希望最终得到一个树,其根有两个子节点,大小为1024和10.左子节点没有实际子节点,但右节点有一个大小为2的右子级。(隐含大小为8的左侧。)该节点依次有一个大小为0的右子,值为“hello”。 (此列表具有从1开始的索引,但基于0的索引类似。)

因此,您需要递归地将索引分解为其二进制部分,并根据需要添加节点。搜索列表时,在遍历具有空子节点的节点时需要注意

答案 4 :(得分:0)

一个非常简单的解决方案是使用GetFirst()来获取树的第一个节点(这只是找到树的最左边的节点)。如果索引N为0,则返回第一个节点。否则,调用GetNodeNext()N次以获取适当的节点。这不是超级高效的,因为通过索引访问节点需要O(N Lg N)时间。

Node *Tree::GetFirstNode()
{
    Node *pN,*child;
    pN=GetRootNode();
    while(NOTNIL(child=GetNodeLeft(pN)))
    {
        pN=child;
    }
    return(pN);
}


Node *Tree::GetNodeNext(Node *pNode)
{
    Node *temp;

    temp=GetNodeRight(pNode);
    if(NOTNIL(temp))
    {
        pNode=temp;
        temp=GetNodeLeft(pNode);
        while(NOTNIL(temp))
        {
            pNode=temp;
            temp=GetNodeLeft(pNode);
        }
        return(pNode);
    }
    else
    {
        temp=GetNodeParent(pNode);
        while( (NOTNIL(temp)) && (GetNodeRight(temp)==pNode) )
        {
            pNode=temp;
            temp=GetNodeParent(pNode);
        }
        return(temp);
    }
}