【问题标题】:Building Red-Black Tree from sorted array in linear time在线性时间内从排序数组构建红黑树
【发布时间】:2021-02-01 21:40:06
【问题描述】:

我知道如何用 n 个插入来构建它(每个插入的效率为 O(log(n))) (n*log(n)) 总体 ,我也知道2-3-4树的等效结构也可以从排序数组中用线性时间构建。 谁能提供一个关于红黑版本的简单解释?

【问题讨论】:

  • 能否请您详细说明您展示代码必要部分的努力?
  • 我并不想编写代码。只是为了理解这个概念。
  • 如果您知道如何构建 2-3-4 树,只需执行完全相同的操作,但通常对应的 3 节点为红色,4 节点为两个红色。跨度>

标签: algorithm data-structures tree big-o red-black-tree


【解决方案1】:

无论您要构建哪种 BST。算法将是相同的。只需要构建平衡二叉树。

  1. 将中间元素放在当前位置
  2. 放置[开始;中)元素到左子树。
  3. 将(中间;结束)元素放在右子树中。

这是 O(N) 算法。可以看出,结果树是平衡的。

我们有平衡树,所以根据定义:

长度(最长路径)-长度(最短路径)

所以你需要将所有节点标记为黑色,除了树中最深的节点(标记为红色)。

【讨论】:

  • 上色怎么样?
  • @SashaMN,关于“它可以显示,结果树将是平衡的”声明的任何链接?
  • 另外,我是否正确理解该算法应该递归应用?
【解决方案2】:

高度为H的完全二叉树有2^H-1个节点。

从排序列表中生成一棵红黑树:

  1. 从列表中删除每隔一个项目,直到您有 2^H-1 个项目剩余一些 H。请注意,您总会有足够的。
  2. 用剩余的项目构建一棵完整的树,全黑。
  3. 现在将您删除的所有项目附加到树上。每个项目都是一个红色节点,连接到其适当位置周围的任何一个黑色节点是叶子。

执行第 (3) 步的最简单方法是对树进行预遍历,将新的红色节点附加到每个黑色叶子上,直到项目用完为止。

注意:Sasha 的算法也有效,但这个显然有效。

【讨论】:

    【解决方案3】:

    从函数数据结构的角度看:Constructing Red-Black Trees 有一篇论文,发现了连续插入的模式,并将其与 1-2 数系统相关。

    读起来很有趣。

    【讨论】:

      【解决方案4】:

      对于用 Java 实现的工作示例,您可能需要查看 Java.util.TreeMap 中的方法 buildFromSorted(int level, int lo, int hi, int redLevel, ...)

      关于 Java 的另一条评论:不幸的是,如果您有自己的数据以排序方式结构化(例如,作为排序的 ArrayLists),那么以线性方式将其放入 TreeMap 并不容易。然而,一种可能性是创建您自己的 SortedMapNavigableMap 实现,该实现由 ArrayList 内部备份。那么就可以使用这个构造函数来高效的构造TreeMap了:

          MySortedMap myMap = new MySortedMap(keyArray, valueArray);
          new TreeMap<K, V> (myMap)
      

      这里有一些示例代码:

          public class MySortedMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V> {
      
              private ArrayList<K> keyArray;
              private ArrayList<V> valueArray;
      
              public Set<Map.Entry<K,V>> entrySet() {
                  return new EntrySet();
              }
      
              class EntryIterator implements Iterator<Map.Entry<K,V>> {
      
                  int i;
      
                  public EntryIterator () {
                      i = 0;
                  }
      
      
                  @Override
                  public boolean hasNext() {
                      if (i < keyArray.size()) {
                          return true;
                      } else {
                          return false;
                      }
                  }
      
                  @Override
                  public Map.Entry<K,V> next() {
                      if (hasNext()) {
                          Map.Entry<K,V> en = new Entry<K,V> (keyArray.get(i), valueArray.get(i));
                          i++;
                          return en;
                      } else {
                          return null;
                      }
                  }
              }
      
              final class Entry<K,V> implements Map.Entry<K,V> {
                  K key;
                  V value;
      
                  @Override
                  public K getKey() {
                      return key;
                  }
      
                  @Override
                  public V getValue() {
                      return value;
                  }
      
                  @Override
                  public V setValue(V value) {
                      this.value = value;
                      return value;
                  }
      
                  public Entry(K key, V value) {
                      this.key = key;
                      this.value = value;
                  }
              }
      
              class EntrySet extends AbstractSet<Map.Entry<K,V>> {
                  public Iterator<Map.Entry<K,V>> iterator() {
                      return new EntryIterator();
                  }
      
                  public int size() {
                      return keyArray.size();
                  }
      
                  
              }
      
              public MySortedMap (ArrayList<K> keyArray, ArrayList<V> valueArray) {
                  if (keyArray.size() != valueArray.size()) {
                      throw new RuntimeException("Key and value arrays must have the same length!");
                  }
      
                  this.keyArray = keyArray;
                  this.valueArray = valueArray;
              }
      
              ... some unused methods ...
          }
      

      【讨论】:

        猜你喜欢
        • 2013-01-31
        • 2011-02-04
        • 2012-06-03
        • 2011-11-19
        • 2011-03-17
        • 2015-05-15
        • 1970-01-01
        • 2011-02-10
        • 2012-09-16
        相关资源
        最近更新 更多