繁体   English   中英

二叉搜索树迭代器c#

[英]Binary search tree iterator c#

我的枚举器中的 MoveNext 方法有问题。 我需要二叉搜索树的迭代器。 在我的枚举器的构造中,我将 Node 初始化为树的根。 Current 是我为下一个项目返回的值。 方法 moveNext 的此代码返回错误值。

public bool MoveNext()
    {

        if (Current == null)
            Current = node.Value;
        else if (node.Left != null)
        {
            node = node.Left;
            Current = node.Value;
        }
        else if (node.Right != null)
        {
            node = node.Right;
            Current = node.Value;
        }
        else
        {
            node.Value = Current;
            do
            {
                if (node.Parent == null)
                    return false;
                node = node.Parent;
            } while (node.Right == null);
            Current = node.Value;
        }
        return true;

    }

我看到该代码存在一些问题。 首先,在else分支中,您正在更改树中节点的值 - 您可能打算编写Current = node.Value; 而不是node.Value = Current; .

然而,这不是主要问题。 你的迭代器很容易陷入无限循环。 向下遍历的一切看起来都是合理的,您可以沿着最左边的路径向下到达叶节点。

然后回溯直到找到一个具有Right子节点的祖先节点并产生该节点的值。 然而,这个值已经在向下的过程中被迭代器返回了。 此外,你不记得你已经走过了哪条路,所以在下一步你将不可避免地再次沿着你之前走的路向下走,然后你会再次原路返回,如此循环往复。

为了解决这个问题,当你回溯时不要停在父节点上——已经迈出了下一条路径的第一步。 确实,这将始终是某个节点的Right孩子,但不一定是第一个祖先的Right孩子,因为您可能已经从该分支回溯。

所以总结一下:如果你不能再往下走,就回溯上一层。 检查您是来自Left子节点还是Right子节点。 如果您来自左侧,则从右侧向下移动(如果存在),并将Current设置为其值。 如果不是,或者如果您已经来自正确的孩子,则向上递归另一个级别。

您的枚举器修改树:

Node.Value = Current;

枚举器不应该这样做。

在最后一个 else 中,您将节点的值更改为与当前节点相同的值:

node.Value = Current;

我认为您尝试将当前节点放在node变量中,但这不是通过将当前值放在当前节点的值中来完成的,并且不需要它,因为node变量已经包含当前节点。

正如 Medo42 指出的那样,如果您来自 Right 节点,则该父节点的所有子节点都已被迭代,因此在寻找父节点以继续迭代时应该检查它:

} while (node.Right == null || node.Right == last);

当您循环父链以找到正确的父链时,您正在使用父链而不是获取子链:

node = node.Right;

所以:

public bool MoveNext() {

    if (Current == null)
        Current = node.Value;
    else if (node.Left != null)
    {
        node = node.Left;
        Current = node.Value;
    }
    else if (node.Right != null)
    {
        node = node.Right;
        Current = node.Value;
    }
    else
    {
        Node last;
        do
        {
            if (node.Parent == null)
                return false;
            last = node;
            node = node.Parent;
        } while (node.Right == null || node.Right == last);
        node = node.Right;
        Current = node.Value;
    }
    return true;

}

我在这里发布了我的解决方案Binary Search Tree Iterator java

源代码https://github.com/yan-khonski-it/bst/blob/master/bst-core/src/main/java/com/yk/training/bst/iterators/BSTIterator.java

这是如何执行此操作的算法(您可以用您喜欢的任何语言实现它)。

数组迭代器

BSTITerator 什么在引擎盖下使用数组。

执行中序遍历并将访问过的节点收集到列表中。 数组迭代器。 现在它的工作方式类似于列表迭代器,很容易实现。

next()hasNext() - 具有恒定的时间复杂度; 然而,这个迭代器需要树的 N 个元素的内存。

堆栈迭代器

next()调用中要返回的所有节点都存储在堆栈中。 每次返回下一个节点时,都会从堆栈中删除元素(让我们将其命名为currentNode )。 如果currentNode有一个右孩子(您已经返回左),您将右孩子放入堆栈。 然后你需要迭代右孩子的左子树并将所有左元素放入堆栈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM