我在试着寻找二叉搜索树的定义我发现到处都是不同的定义。
有人说,对于任何给定的子树,左子键都小于或等于根键。
有人说,对于任何给定的子树,右子键大于或等于根键。
我以前的大学数据结构书说“每个元素都有一个键,没有两个元素有相同的键。”
bst有一个通用的定义吗?特别是关于如何处理具有相同键的多个实例的树。
编辑:也许我不清楚,我看到的定义是
1)左<=根<右
2)左<根<=右
3)左<根<右,这样就不存在重复的键。
我在试着寻找二叉搜索树的定义我发现到处都是不同的定义。
有人说,对于任何给定的子树,左子键都小于或等于根键。
有人说,对于任何给定的子树,右子键大于或等于根键。
我以前的大学数据结构书说“每个元素都有一个键,没有两个元素有相同的键。”
bst有一个通用的定义吗?特别是关于如何处理具有相同键的多个实例的树。
编辑:也许我不清楚,我看到的定义是
1)左<=根<右
2)左<根<=右
3)左<根<右,这样就不存在重复的键。
当前回答
如果您的二叉搜索树是红黑树,或者您打算进行任何类型的“树旋转”操作,重复的节点将导致问题。假设你的树规则是这样的:
左<根<=右
现在想象一个简单的树,它的根是5,左子结点是nil,右子结点是5。如果你在根结点上做一个左旋转你会在左子结点中得到一个5在根结点中得到一个5而右子结点为nil。现在左树中的某个元素等于根结点,但上面的规则假设左<根结点。
我花了几个小时试图弄清楚为什么我的红/黑树偶尔会乱序,问题就是我上面描述的。希望有人读了这篇文章,将来可以节省调试的时间!
其他回答
你说的三件事都是真的。
密钥是唯一的 左边是比这个小的键 右边是比这个大的键
我想你可以把你的树倒过来,把较小的键放在右边,但实际上“左”和“右”的概念只是:一个可视化的概念,帮助我们思考一个没有真正的左或右的数据结构,所以这并不重要。
在使用红黑树实现时,我遇到了用多个键验证树的问题,直到我意识到使用红黑插入旋转时,必须放松对的约束
左<=根<=右
由于我所查看的任何文档都不允许重复键,而且我不想重写旋转方法来解释它,所以我决定修改节点以允许节点内的多个值,并且树中不允许重复键。
许多算法将指定排除重复项。例如,麻省理工学院算法书中的示例算法通常会给出没有重复的示例。实现副本相当简单(在节点上作为列表,或者在一个特定方向上)。
大多数(我见过的)将左子节点指定为<=,右子节点指定为>。实际上,允许右子节点或左子节点中的任何一个等于根节点的BST将需要额外的计算步骤来完成允许重复节点的搜索。
最好利用节点上的列表来存储重复项,因为在节点的一侧插入'='值需要重写这一侧的树以将该节点作为子节点,或者将该节点作为子节点放置在下面的某个位置,这降低了一些搜索效率。
你必须记住,大多数课堂上的例子都是为了描述和传达概念而简化的。在现实世界的许多情况下,它们一文不值。但是,“每个元素都有一个键,并且没有两个元素具有相同的键”这句语句不会因为在元素节点上使用列表而违反。
所以按照你的数据结构书上说的去做吧!
编辑:
二叉搜索树的通用定义涉及基于在两个方向之一遍历数据结构的基础上存储和搜索键。从实际意义上讲,这意味着如果值<>,则在两个“方向”之一遍历数据结构。所以,在这种情况下,重复的值没有任何意义。
这与BSP或二进制搜索分区不同,但也不是完全不同。搜索算法有两个“旅行”方向之一,否则它就完成了(成功与否)。所以我很抱歉,我最初的答案没有解决“通用定义”的概念,因为重复的内容实际上是一个不同的主题(在成功搜索之后处理的内容,而不是作为二分搜索的一部分)。
元素排序关系<=是一个总顺序,因此关系必须是自反的,但通常二叉搜索树(又名BST)是一个没有重复的树。
否则,如果有重复你需要运行两次或更多相同的功能删除!
1.)左<=根<右 2.)左<根<=右 3.)左<根<右,这样就不存在重复的键。
我可能要去翻出我的算法书籍,但我的头脑中(3)是标准形式。
(1)或(2)只在你开始允许重复的节点并且你把重复的节点放在树本身(而不是包含列表的节点)时才会出现。