Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Data structures 为什么Clojure食谱中的红黑树漏掉了Recoring案例_Data Structures_Clojure_Tree_Red Black Tree - Fatal编程技术网

Data structures 为什么Clojure食谱中的红黑树漏掉了Recoring案例

Data structures 为什么Clojure食谱中的红黑树漏掉了Recoring案例,data-structures,clojure,tree,red-black-tree,Data Structures,Clojure,Tree,Red Black Tree,在处理了中的红黑树实现示例之后,我注意到平衡函数不包含重新排序的情况。(大多数红黑树文献中的情况1,或者也称为插入节点的父节点为红色的情况) 下面是一个小例子: 在树a中插入数字8,我认为应该通过重新排序第二级生成树b。Clojure Cookbook中的实现不必要地旋转树,从而生成树c 是否有充分的理由在实现中忽略此情况?在纯功能设置中,改变节点的颜色不是一个选项。在命令式实现中,重新排序而不是旋转可以保存一些指针分配,但在功能性实现中,您必须创建所需颜色的新节点,并在构造中为父节点中的子节

在处理了中的红黑树实现示例之后,我注意到平衡函数不包含重新排序的情况。(大多数红黑树文献中的情况1,或者也称为插入节点的父节点为红色的情况)

下面是一个小例子:

在树
a
中插入数字
8
,我认为应该通过重新排序第二级生成树
b
。Clojure Cookbook中的实现不必要地旋转树,从而生成树
c


是否有充分的理由在实现中忽略此情况?

在纯功能设置中,改变节点的颜色不是一个选项。在命令式实现中,重新排序而不是旋转可以保存一些指针分配,但在功能性实现中,您必须创建所需颜色的新节点,并在构造中为父节点中的子节点进行分配。您还将注意到,此实现比传统的命令式版本更简单。

我是此特定配方的作者

大多数红黑树实现和教科书都假设一个可变的上下文,在这个上下文中您可以就地更新特定的节点。在这种情况下,更改节点的颜色肯定比树旋转便宜

然而,Clojure Book的实现是纯功能性的,这意味着没有突变。因此,无论您是重新对节点进行排序还是创建新的子树,成本都是相同的,因为我们无论如何都要复制节点。因此,我们采用旋转。这使得平衡功能尽可能简单,同时保持所有红黑属性

此实现的灵感来自Chris Okasaki的书。这是一个很好的参考,我会推荐给任何对持久数据结构感兴趣的人

(defn balance
  "Ensures the given subtree stays balanced by rearranging black nodes
  that have at least one red child and one red grandchild"
  [tree]
  (match [tree]
         [(:or ;; Left child red with left red grandchild
               [:black [:red [:red a x b] y c] z d]
               ;; Left child red with right red grandchild
               [:black [:red a x [:red b y c]] z d]
               ;; Right child red with left red grandchild
               [:black a x [:red [:red b y c] z d]]
               ;; Right child red with right red grandchild
               [:black a x [:red b y [:red c z d]]])] [:red [:black a x b]
                                                            y
                                                            [:black c z d]]
               :else tree))