我知道如何通过 n 次插入(每次都具有O(log(n))的效率)来构建它,总共需要(n*log(n))的时间。我还知道从排序后的数组中可以线性时间构建等价于2-3-4树的结构。请问有人能提供关于红黑树版本的简单解释吗?
长度(最长路径) - 长度(最短路径)<= 1
所以你需要将所有节点标记为黑色,除了树中最深的节点(将它们标记为红色)。关于Java的一个工作示例,您可以查看Java.util.TreeMap
中的buildFromSorted(int level, int lo, int hi, int redLevel, ...)
方法。
再谈Java:不幸的是,如果您自己的数据以排序方式结构化(例如,作为已排序的ArrayLists),那么将其线性地放入TreeMap并不容易。然而,一种可能性是创建自己的SortedMap
或NavigableMap
实现,该实现在内部由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 ...
}