Title: Trees 3: Construction of Dynamic Binary Trees
1Trees 3 Construction of Dynamic Binary Trees
- Andy Wang
- Data Structures, Algorithms, and Generic
Programming
2Overview
- Definition of class TBinaryTree
- Recursive methods
- Inserting elements
- Removing elements
- Binary tree construction from file
3Defining Class TBinaryTree
- template lttypename Tgt
- class TBinaryTree
- friend class TBinaryTreeNavigatorltTgt
- public
- typedef T value_type
- // constructors
- TBinaryTree()
- virtual TBinaryTree()
- TBinaryTree(const TBinaryTreeltTgt B)
- TBinaryTreeltTgt operator(const TBinaryTreeltTgt
B) - // read-only operations
- int Empty() const
- size_t Size() const
- int Height() const
4Defining Class TBinaryTree
- void Display(stdostream os, char ofc \0)
const - void Dump(stdostream os, chcar ofc) const
- void Dump(stdostream os, const T fill, char
ofc) const - // operations
- int InsertRoot(const T t)
- int InsertLeft(Navigator N, const T t)
- int InsertRight(Navigator N, const T t)
- int Insert(Iterator I, const T t)
- int Remove(Iterator I)
- size_t Remove(const T t)
- void Clear()
- void Clear(Navigator N) // clear subtree with
root N
5Defining Class TBinaryTree
- // iterator operators
- typedef TBinaryTreeInorderIteratorltTgt Iterator
- typedef TBinaryTreePreorderIteratorltTgt
PreorderIterator - typedef TBinaryTreePostorderIteratorltTgt
PostorderIterator - typedef TBinaryTreeLevelorderIteratorltTgt
LevelorderIterator - typedef TBinaryTreeNavigatorltTgt Navigator
- Navigator Root() const
- Iterator Begin() const
- Iterator End() const
- Iterator rBegin() const
- Iterator rBegin() const
6Defining Class TBinaryTree
- protected
- class TNode
- friend class TBinaryTreeltTgt
- friend class TBinaryTreeNavigatorltTgt
- TNode(const T)
- TNode(const TNode)
-
- T value
- char color
- TNode parent, lchild, rchild
-
- TNode root
- static void RRelease(TNode N) // recursive
deletion of Ns children - static TNode RClone(const TNode N) // deep
copy of N - static size_t RSize(const TNode N) // return
number of nodes at N - static int RHeight(const TNode N) // return
height of tree at N
7Recursive Protected Methods
- template lttypename Tgt
- size_t TBinaryTreeltTgtRSize(const TNode N)
- if (N 0) return 0
- return (1 RSize(N-gtlchild)
RSize(N-gtrchild)) -
- template lttypename Tgt
- int TBinaryTreeltTgtRHeight(const TNode N)
- if (N 0) return -1
- return (1 max(RHeight(N-gtlchild),
RHeight(N-gtrchild)))
8Recursive Protected Methods
- template lttypename Tgt
- void TBinaryTreeltTgtRRelease(TBinaryTreeltTgtTNod
e N) - if (N ! 0)
- if (N-gtlchild ! 0)
- TBinaryTreeltTgtRRelease(N-gtlchild)
- delete N-gtlchild
- N-gtlchild 0
-
- if (N-gtrchild ! 0)
- TBinaryTreeltTgtRRelease(N-gtrchild)
- delete N-gtrchild
- N-gtrchild 0
-
-
9Recursive Protected Methods
- template lttypename Tgt
- TBinaryTreeltTgtTNode
- TBinaryTreeltTgtRClone(const TBinaryTreeltTgtTNode
N) - if (N 0) return 0
- TBinaryTreeltTgtTNode newN new
TBinaryTreeltTgtTNode(N-gtvalue) - newN-gtlchild TBinaryTreeltTgtRClone(N-gtlchild)
- newN-gtrchild TBinaryTreeltTgtRClone(N-gtrchild)
-
- if (newN-gtlchild)
- newN-gtlchild-gtparent newN
-
- if (newN-gtrchild)
- newN-gtrchild-gtparent newN
-
- return newN
10Recursive Protected Calls
- template lttypename Tgt
- void TBinaryTreeltTgtDump(ostream os, const T
fill) const - // idea BFS
1
root
2
3
4
5
11Recursive Protected Calls
- template lttypename Tgt
- void TBinaryTreeltTgtDump(ostream os, const T
fill) const - if (root 0) return
- TBinaryTreeltTgtTNode fillNode new
TBinaryTreeltTgtTNode(fill) - CQueueltTListltTBinaryTreeltT, PgtTNode gt gt Que
- TBinaryTreeltTgtTNode current
- unsigned int currLayerSize, nextLayerSize, j, k
- Que.Push(root)
- k 1 // always 2(layer number)
- for (curLayerSize 1, nextLayerSize 0
- currLayerSize gt 0
- currLayerSize nextLayerSize)
-
12Recursive Protected Calls
- for (j 0 j lt k j)
- current Que.Front()
- Que.Pop()
- os ltlt current-gtvalue
- if (current-gtlchild ! 0)
- Que.Push(current-gtlchild)
- nextLayerSize
- else
- Que.Push(fillNode)
-
- if (current-gtrchild ! 0)
- Que.Push(current-gtrchild)
- nextLayerSize
- else
- Que.Push(fillNode)
-
-
- os ltlt endl
- k 2
13Recursive Protected Calls
- Que.Clear()
- delete fillNode
14Helper Functions
- template lttypename Tgt
- int TBinaryTreeltTgtEmpty() const return (root
0) - template lttypename Tgt
- int TBinaryTreeltTgtHeight() const return
RHeight(root) - template lttypename Tgt
- size_t TBinaryTreeSize() const return
RSize(root) - template lttypename Tgt
- void TBinaryTreeltTgtClear()
- TBinaryTreeltTgtRRelease(root)
- delete root
- root 0
15Helper Functions
- template lttypename Tgt
- void TBinaryTreeltTgtClear(TBinaryTreeNavigatorltTgt
N) - if (N.Valid())
- TNode P N.currentNode-gtparent
- if (N.IsLeftChild())
- P-gtlchild 0
- else if (N.IsRightChild())
- P-gtrchild 0
-
- TBinaryTreeltTgtRRelease(N.currNode)
- delete N.currNode
- N.currNode P
-
16Helper Functions
- template lttypename Tgt
- TBinaryTreeltTgt TBinaryTreeltTgtoperator(const
TBinaryTreeltTgt b) - if (this ! b)
- Clear()
- root TBinaryTreeltTgtRClone(b.root)
-
- return this
17Supports for Iterators and Navigators
- template lttypename Tgt
- TBinaryTreeInorderIteratorltTgt TBinaryTreeltTgtBegi
n() const - TBinaryTreeltTgtIterator I
- I.Initialize(this)
- return I
-
- template lttypename Tgt
- TBinaryTreeInorderIteratorltTgt TBinaryTreeltTgtEnd(
) const - TBinaryTreeltTgtIterator I
- return I
-
18Supports for Iterators and Navigators
- template lttypename Tgt
- TBinaryTreeInorderIteratorltTgt TBinaryTreeltTgtrBeg
in() const - TBinaryTreeltTgtIterator I
- I.rInitialize(this)
- return I
-
- template lttypename Tgt
- TBinaryTreeInorderIteratorltTgt TBinaryTreeltTgtrEnd
() const - TBinaryTreeltTgtIterator I
- return I
-
- template lttypename Tgt
- TBinaryTreeNavigatorltTgt TBinaryTreeltTgtRoot()
const - TBinaryTreeltTgtNavigator N
- N.currNode root
- return N
-
19Constructors
- template lttypename Tgt
- TBinaryTreeltTgtTNodeTNode(const T t)
value(t), color(b), parent(0), lchild(0),
rchild(0) -
- template lttypename Tgt
- TBinaryTreeltTgtTNodeTNode(const TNode N)
- stdcerr ltlt TBinaryTreeltTgtTNodeTNode(const
TNode) called\n -
- template lttypename Tgt
- TBinaryTreeltTgtTBinaryTree() root(0)
- template lttypename Tgt
- TBinaryTreeltTgtTBinaryTree() Clear()
- template lttypename Tgt
- TBinaryTreeltTgtTBinaryTree(const TBinaryTreeltTgt
b) - root TBinaryTreeltTgtRClone(b.root)
-
20Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtInsertRoot(const T t)
- if (root ! 0)
- root-gtvalue t
- return 1
-
- root new TBinaryTreeltTgtTNode(t)
- if (root 0)
- return 0
-
- return 1
21Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtInsertLeft(Navigator N,
const T t) - if (!N.Valid())
- return 0
-
- if (N.HasLeftChild())
- N
- N t
- return 1
-
- N.currNode-gtlchild new TBinaryTreeltTgtTNode(t)
- if (N.currNode-gtlchild 0)
- return 0
-
- N.currNode-gtlchild-gtparent N.currNode
- N
- return 1
22Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtInsertRight(Navigator N,
const T t) - if (!N.Valid())
- return 0
-
- if (N.HasRightChild())
- N
- N t
- return 1
-
- N.currNode-gtrchild new TBinaryTreeltTgtTNode(t)
- if (N.currNode-gtrchild 0)
- return 0
-
- N.currNode-gtrchild-gtparent N.currNode
- N
- return 1
23Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtInsert(TBinaryTreeltTgtIterato
r I, const T Tval) - // empty case insert at root
- if (Empty())
- if (InsertRoot(Tval)
- I.N Root()
- return 1
- else
- return 0
-
-
-
24Tree Operations
- // valid case, insert Tval at I, move Told to
I - if (I.Valid())
- T Told I
- Navigator N I.N
- if (N.HasRightChild()))
- N
- while (N.HasLeftChild())
- N
-
- if (!InsertLeft(N, Told))
- return 0
-
- else
- if (!InsertRight(N, Told))
- return 0
-
-
- I Tval
- return 1
Told
I -gt
25Tree Operations
- // valid case, insert Tval at I, move Told to
I - if (I.Valid())
- T Told I
- Navigator N I.N
- if (N.HasRightChild()))
- N
- while (N.HasLeftChild())
- N
-
- if (!InsertLeft(N, Told))
- return 0
-
- else
- if (!InsertRight(N, Told))
- return 0
-
-
- I Tval
- return 1
Tval
I -gt
Told
26Tree Operations
- // valid case, insert Tval at I, move Told to
I - if (I.Valid())
- T Told I
- Navigator N I.N
- if (N.HasRightChild()))
- N
- while (N.HasLeftChild())
- N
-
- if (!InsertLeft(N, Told))
- return 0
-
- else
- if (!InsertRight(N, Told))
- return 0
-
-
- I Tval
- return 1
Told
I -gt
27Tree Operations
- // valid case, insert Tval at I, move Told to
I - if (I.Valid())
- T Told I
- Navigator N I.N
- if (N.HasRightChild()))
- N
- while (N.HasLeftChild())
- N
-
- if (!InsertLeft(N, Told))
- return 0
-
- else
- if (!InsertRight(N, Told))
- return 0
-
-
- I Tval
- return 1
Tval
I -gt
Told
28Tree Operations
- // invalid iterator insert at the end
- for (I.N Root() I.N.HasRightChild() (I.N))
- if (InsertRight(I.N, Tval)
- return 1
- else
- I End()
- return 0
-
29Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtRemove(Iterator I)
- // remove element at I, leave I at (), and
preserve inorder - if (!I.Valid())
- return 0
-
- TBinaryTreeltTgtNavigator N I.N
- I // I is now at the next place in an inorder
traversal - TBinaryTreeltTgtTNode R N.currNode-gtrchild
- TBinaryTreeltTgtTNode L N.currNode-gtlchild
- TBinaryTreeltTgtTNode P N.currNode-gtparent
-
N-gt
I-gt
30Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtRemove(Iterator I)
- // remove element at I, leave I at (), and
preserve inorder - if (!I.Valid())
- return 0
-
- TBinaryTreeltTgtNavigator N I.N
- I // I is now at the next place in an inorder
traversal - TBinaryTreeltTgtTNode R N.currNode-gtrchild
- TBinaryTreeltTgtTNode L N.currNode-gtlchild
- TBinaryTreeltTgtTNode P N.currNode-gtparent
-
N-gt
I-gt
31Tree Operations
- template lttypename Tgt
- int TBinaryTreeltTgtRemove(Iterator I)
- // remove element at I, leave I at (), and
preserve inorder - if (!I.Valid())
- return 0
-
- TBinaryTreeltTgtNavigator N I.N
- I // I is now at the next place in an inorder
traversal - TBinaryTreeltTgtTNode R N.currNode-gtrchild
- TBinaryTreeltTgtTNode L N.currNode-gtlchild
- TBinaryTreeltTgtTNode P N.currNode-gtparent
-
P-gt
N-gt
L-gt
R-gt
I-gt
32Tree Operations
- Nodes listed in inorder traversal before removal
L, N, I, R, P - Nodes listed after removing N
- L, I, R, P
P-gt
N-gt
L-gt
R-gt
I-gt
33Tree Operations
- Nodes listed in inorder traversal before removal
L, N, I, R, P - Nodes listed after removing N
- L, I, R, P
- How do we reconnect
- L, P, and R?
P-gt
L-gt
R-gt
I-gt
34Tree Operations
- Nodes listed in inorder traversal before removal
L, N, I, R, P - Nodes listed after removing N
- L, I, R, P
- How do we reconnect
- L, P, and R?
P-gt
L-gt
35Tree Operations
- // case 1 N has right child
- if (N.HasRightChild())
- if (I.N.HasLeftChild())
- stdcerr ltlt Error structural problem ltlt
endl - return 0
-
- if (L)
- I.N.currNode-gtlchild L
- L-gtparent I.N.currNode
- N.currNode-gtlchild 0
-
P-gt
N-gt
L-gt
R-gt
I-gt
36Tree Operations
- // case 1 N has right child
- if (N.HasRightChild())
- if (I.N.HasLeftChild())
- stdcerr ltlt Error structural problem ltlt
endl - return 0
-
- if (L)
- I.N.currNode-gtlchild L
- L-gtparent I.N.currNode
- N.currNode-gtlchild 0
-
P-gt
N-gt
L-gt
R-gt
I-gt
37Tree Operations
- // case 1 N has right child
- if (N.HasRightChild())
- if (I.N.HasLeftChild())
- stdcerr ltlt Error structural problem ltlt
endl - return 0
-
- if (L)
- I.N.currNode-gtlchild L
- L-gtparent I.N.currNode
- N.currNode-gtlchild 0
-
P-gt
N-gt
R-gt
I-gt
38Tree Operations
- // case 1 N has right child
- if (N.HasRightChild())
- if (I.N.HasLeftChild())
- stdcerr ltlt Error structural problem ltlt
endl - return 0
-
- if (L)
- I.N.currNode-gtlchild L
- L-gtparent I.N.currNode
- N.currNode-gtlchild 0
-
P-gt
N-gt
R-gt
I-gt
39Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
40Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
41Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
42Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
43Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
44Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
P-gt
N-gt
R-gt
I-gt
45Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
N-gt
root-gt
R-gt
I-gt
46Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
N-gt
root-gt
R-gt
I-gt
47Tree Operations
- if (N.IsLeftChild())
- P-gtlchild R
- R-gtparent P
- else if (N.IsRightChild())
- P-gtrchild R
- R-gtparent P
- else
- root R
- R-gtparent 0
-
- delete N.currNode
- return 1
-
-
N-gt
root-gt
R-gt
I-gt
48Tree Operations
I-gt
P-gt
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
N-gt
L-gt
49Tree Operations
I-gt
P-gt
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
50Tree Operations
P-gt
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
N-gt
L-gt
51Tree Operations
P-gt
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
52Tree Operations
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
N-gt
root-gt
L-gt
53Tree Operations
- // case 2 N has no right child and has parent
- if (N.IsLeftChild())
- P-gtlchild L
- if (L)
- L-gtparent P
-
- else if (N.IsRightChild())
- P-gtrchild L
- if (L)
- L-gtparent P
-
- else // case 3 N has no right child and
has no parent - root L
- if (L)
- L-gtparent 0
-
-
- delete N.currNode
- return 1
root-gt
54Tree Operations
- template lttypename Tgt
- size_t TBinaryTreeltTgtRemove(const T t)
- size_t count(0)
- TBinaryTreeltTgtIterator I Begin()
- while (I.Valid())
- if (t I)
- Remove(I)
- count
- else
- I
-
-
- return count
-
-