(Latest Revision: 04/17/2005))
Ways To Represent A Binary Tree
This table:
Index element left right
0 -- -- 5 <--- pointer to root
1 A 0 0
2 B 1 3
3 C 0 0
4 D 2 0
5 E 4 6
6 F 0 0
represents this tree:
E
/ \
/ \
/ \
D F
/
/
B
/ \
/ \
/ \
A C
- Advantages:
- Easy structure in which to search
- Easy to insert
- Easy to delete
- Easy to read tree back in from disk after writing out
(no recreation of links required)
- The programmer can link unused table entries into a "free list." and
can write functions to allocate and deallocate entries in the table
for use as tree nodes.
- Disadvantages:
- Memory allocation is not truly dynamic and it can be difficult to
match the array size with the size range of the tree.
This table:
E D B A C K J F R P <-- element
y y y n y n n n y n <-- has lft child
y n y n y n n y n n <-- has rt child
(F) (C) (J) (R)
represents this tree: Dynamic Reconstruction Rules:
E I. The root is first
/ \
/ \ II. If a node X has a left child C,
/ \ C comes right after X in the list.
D F
/ \ III. If a node R is not a left child (and
/ \ not the root) then R is the right
B R child of the nearest prior node with
/ \ / a right child that has not been
/ \ / reconstructed yet.
/ \ P
A C
/ \
/ \
K J
- Advantages:
- Very compact - elements of the 2nd and 3rd rows can be 1-bit each
- Disadvantages:
- Insertion and deletion would require O(N) data movement
- ???
This array X:
A E R I - L - T Z - -
1 2 3 4 5 6 7 8 9 10 11
represents this tree:
A
/ \ * parent(X[n]) X[floor(n/2)]
/ \ * if (n even)
/ \ sibling(X[n]) = X[n+1]
E R else sibling(X[n]) = X[n-1]
/ / * left child(X[n]) = X[2n]
/ / * right child(X[n]) = X[2n+1]
/ /
I L
/ \
/ \
T Z
- Advantages:
- compact representation of 'complete' trees
- no explicit pointers, yet 'implicit' pointers are easy to follow
-
- Disadvantages:
- not a compact representation for binary trees of some shapes
- storage is not dynamic