i know how to build it with n insertions ( each with O(log(n)) efficiency ) (n*log(n)) overall ,i also know that the equivalent structure of 2-3-4 tree can also be build with linear time from sorted array. can anyone please provide a simple explanation about the red-black version?
-
Could you please elaborate us your effort showing the necessary part of the code? – Enamul Hassan Jan 24 '16 at 00:44
-
i am not trying to code it. just to understand the concept. – Michael G Jan 24 '16 at 01:13
-
If you know how to build a 2-3-4 tree, just do exactly the same thing but a red for a 3 node, and two reds for a 4 node in the usual correspondence. – rici Jan 24 '16 at 04:08
4 Answers
No matter what kind of BST you are going to build. The algorithm will be the same. Only need to build balanced binary tree.
- Place middle element to the current position
- Place [begin; middle) elements to the left subtree.
- Place (middle; end) elements to the right subtree.
This is O(N) algorithm. It can be shown, that the result tree will be balanced.
We have balanced tree, so by definition:
length(longest path) - length(shortest path) <= 1
So you need to mark all nodes as black, except the deepest nodes in the tree (mark them as red).

- 708
- 5
- 16
-
1
-
@SashaMN, Any link about the claim "it can be shown, that the result tree will be balanced"? – Rauni Lillemets Feb 01 '21 at 08:38
-
Also, do I understand correctly that this algorithm should be applied recursively? – Rauni Lillemets Feb 01 '21 at 08:47
A complete binary tree of height H has 2^H-1 nodes.
To make a red black tree from a sorted list:
- Remove every second item from the list until you have 2^H-1 items remaining for some H. Note that you will always have enough.
- Build a complete tree out of the remaining items, all black.
- Now attach all the items you removed to the tree. Each item will be a red node, attached to whichever of the black nodes around its proper position is a leaf.
The easiest way to do step (3) is just to do a pre-order traversal of the tree, attaching new red nodes to every black leaf until you run out of items.
NOTE: Sasha's algorithm also works, but this one obviously works.

- 53,709
- 3
- 46
- 87
From a functional data structure perspective: there is a paper for Constructing Red-Black Trees, which discovered the pattern of continuous insertion and related it to 1-2 number system.
It's a fun read.

- 318
- 2
- 7
For a working example implemented in Java, you may want to check out the method buildFromSorted(int level, int lo, int hi, int redLevel, ...)
in Java.util.TreeMap
.
One more comment about Java in particular: Unfortunately, if you have your own data structured in a sorted manner (e.g. as sorted ArrayLists), it is not so easy to get it into a TreeMap in a linear manner. One possibility however is to create your own implementation of a SortedMap
or NavigableMap
which is backed up by an ArrayList internally. Then it is possible to use this constructor to efficiently construct the TreeMap:
MySortedMap myMap = new MySortedMap(keyArray, valueArray);
new TreeMap<K, V> (myMap)
Here is some sample code for doing so:
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 ...
}

- 2,299
- 1
- 26
- 39