• Top node = root
• Left and right subtree
• Node 1 is a parent of node 2,5,6.– Node 2 is a parent of node 3,4 == – Node 3,4 are children of node 2.
• Node 3 and 4 are siblings.
• Node 1 is an ancestor of node 7.
• Node that does not have any branch going out = leaf. In the picture, the leaves are 3, 4, 5 and 7.
• Notice: there is only 1 path from a root to a node.
• depth of node n is the path length from root to n. – Example: depth of node 7 is 2.
• Height of n is the maximum path length from n to leaf.– Example: height of node 7 is 0. – Height of node 1 is 2.
• Height of a tree = = height of its root.– If a tree only has root, we let its height be 0.
For empty tree, we let its height be -1. – height of any tree = = height of its heighest
subtree +1.
• level of a node– A child of a node has 1 more level than its
parent.– A root has its level = = 0.
If a node can have any number of branches?
• We can never be sure of the number of branches?
• Preparing many branches in advance is a waste of space.
• One solution! -> Data
Link to its first child.
Link to next sibling.
1
2 5
3
6
4 7
How to arrange nodes for printing
• preorder – Pick the root first– Then pick subtree
• Within subtree, pick its root first, and so on….
Second, this subtree
Inside, we also view it with preorder.
5.2.
1.
4.3.
6.
7.
First to pick
Third
4th, this subtree
Inside, it is also preorder.
Preorder result is 1,2,3,4,5,6,7
• postorder– View all subtrees, then the root.
– Inside each subtree, use postorder.
– The postorder result of our example is 3425, , , ,7 ,6 ,1 .
• inorder – Left subtree comes first, then root, then right subtree.
– Inside each subtree, use inorder.
– The inorder result of our example is (we do not count a subtree that has 5 because we do not know which side it will be on 324167) , , , , ,
breadth-first search
• The first 3 methods we have seen are tree-searching using depth-first search– When looking at each subtree, we must finish
with the whole of that subtree before we can carry on.
• breadth-first inspects a tree level by level, starting from root.– Our example tree then gives the following
result. -> 1256347, , , , , ,
breadth-first implementation
• When we look at a node, we record the children of that node into a queue created for storing next level nodes (next level queue).
• Example: if we have
d
-
e
*
a
+
*
cb
breadth-first implementation(2)• When we look at the root, we record itsildren into n
ext level queue. Therefore, at this stage, next level queue has + and –.
• this level queue = next level queue; clear next levelqueue
• Inspect this level queue. – Find +: Now we insert the children of + into next level qu
eue– At this stage, next level queue = a,*
• Continue inspecting this level queue, – we find – :Now we insert the children of - into next level
queue– At this stage, next level queue = a,*,d,e
• No more member in this level queue, therefore let t his level queue = next level queue.
– At this stage, this level queue = a,*,d,e
• Now starting with this level queue again. And so on.
Binary Tree
• Each node can have at most 2 branches.
• It is possible to have one branch at every level, meaning it is a linked list (skewed tree).
complete tree • Full up to the level before the highest
level.
• At the highest level, leaves must fill from left to right. A
E
O
N
XT
Full is complete, but complete is not full.
complete tree(2)
• If we put members of a complete binary tree into an array, breadth-first: – Member at the i_th position will have its left child at
the 2i+1 th position. – And its right child will be at 2i+2 th position. – A parent of i is at the (i-1)/2 th position (no decimal)
A N E T O X
Example: left child of E must have index = = 2*2+1 =5. It is X.The parent of E must have index == (2-1)/2 = 0
Binary tree : Theory
Let• leaves(t) be the number of leaves in the tree t.• n(t) be the number of nodes of tree t. • height(t) be the height of t. • leftsubtree(t) be the left subtree of t.• rightsubtree(t) be the right subtree of t.• max(a,b) be a maximum value from a and b.
For a non empty binary tree, we have the following relations:
0.2
1)()(
tntleaves
)(20.2
1)( theighttn
If t is a -two tree, then 0.2
1)()(
tntleaves
If 0.2
1)()(
tntleaves Then t is definitely a tw
-o tree.
If t is a full tree, )(20.2
1)( theighttn
Proving 0.2
1)()(
tntleaves
base case is when our tree has only its root.
1)( tleaves
1 2.0
1n(t)
Which is true. inductive case is when our tree has height h.
Let
0.2
1)()(
tntleaves
We must prove that when t has height = h+1, then0.2
1)()(
tntleaves
2.0
1tree(t))n(rightsub
0.2
1ree(t))n(leftsubt
t))htsubtree(leaves(rig ))tsubtree(tleaves(lef leaves(t)
We know that: 1 tree(t))n(rightsub ree(t))n(leftsubt n(t)
We can substitute n(t) into our equation.
0.2
1)()(
tntleaves
Fact about External Path length
• Let t be a binary tree that has root. External Path length, E(t), is the sum of the depth of all leaves.
• If t is a binary tree that has leaves(t) = k (more than 0), then
kktE 2log)2/()(
Binary Search Tree
Is an empty tree or a tree that
• Every member in leftsubtree(t) has smaller value than the member at the root.
• Every member in rightsubtree(t) has larger value than the member at the root.
• Both leftsubtree(t) and rightsubtree(t) are also binary search trees.
7
11
146
5
2
4
•Finding a member is easy. Let us try to find 4. When we look at each node, we know immediately which side of the tree that we should carry on looking. •Therefore the searching time only depends on the height of our tree. The height is a log of n(t).
1. class BinaryNode2. {3. // Constructors4. BinaryNode( Comparable theElement )5. {6. this( theElement, null, null );7. }
8. BinaryNode( Comparable theElement, BinaryNode lt, BinaryNode rt )9. {10. element = theElement;11. left = lt;12. right = rt;13. }
14. // Friendly data; accessible by other package routines15. Comparable element; // The data in the node16. BinaryNode left; // Left child17. BinaryNode right; // Right child18. }
// BinarySearchTree class // // CONSTRUCTION: with no initializer // // ******************PUBLIC OPERATIONS********************* // void insert( x ) --> Insert x // void remove( x ) --> Remove x // Comparable find( x ) --> Return item that matches x // Comparable findMin( ) --> Return smallest item // Comparable findMax( ) --> Return largest item // boolean isEmpty( ) --> Return true if empty; else false // void makeEmpty( ) --> Remove all items // void printTree( ) --> Print tree in sorted order
private BinaryNode root;
1. public class BinarySearchTree2. { 3. private BinaryNode root;
4. /**5. * Construct the tree.6. */7. public BinarySearchTree( )8. {9. root = null;10. }
11. /**12. * Insert into the tree; duplicates are ignored.13. * @param x the item to insert.14. */15. public void insert( Comparable x )16. {17. root = insert( x, root );18. }
19. /**20. * Remove from the tree. Nothing is done if x is not found.21. * @param x the item to remove.22. */23. public void remove( Comparable x )24. {25. root = remove( x, root );26. }
27. /**28. * Find the smallest item in the tree.29. * @return smallest item or null if empty.30. */31. public Comparable findMin( )32. {33. return elementAt( findMin( root ) );34. }
35. /**36. * Find the largest item in the tree.37. * @return the largest item of null if empty.38. */39. public Comparable findMax( )40. {41. return elementAt( findMax( root ) );42. }
43. /**44. * Find an item in the tree.45. * @param x the item to search for.46. * @return the matching item or null if not found.47. */48. public Comparable find( Comparable x )49. {50. return elementAt( find( x, root ) );51. }
52. /**53. * Make the tree logically empty.54. */55. public void makeEmpty( )56. {57. root = null;58. }
59. /**60. * Test if the tree is logically empty.61. * @return true if empty, false otherwise.62. */63. public boolean isEmpty( )64. {65. return root == null;66. }
67. /**68. * Print the tree contents in sorted order.69. */70. public void printTree( )71. {72. if( isEmpty( ) )73. System.out.println( "Empty tree" );74. else75. printTree( root );76. }
77. /**78. * Internal method to get element field.79. * @param t the node.80. * @return the element field or null if t is null.81. */82. private Comparable elementAt( BinaryNode t )83. {84. return t == null ? null : t.element;85. }
86. /**87. * Internal method to insert into a subtree.88. * @param x the item to insert.89. * @param t the node that roots the tree.90. * @return the new root.91. */92. private BinaryNode insert( Comparable x, BinaryNode t )93. {94. /* 1*/ if( t == null )95. /* 2*/ t = new BinaryNode( x, null, null );96. /* 3*/ else if( x.compareTo( t.element ) < 0 )97. /* 4*/ t.left = insert( x, t.left );98. /* 5*/ else if( x.compareTo( t.element ) > 0 )99. /* 6*/ t.right = insert( x, t.right );100./* 7*/ else101./* 8*/ ; // Duplicate; do nothing102./* 9*/ return t;103. }
104. /**105. * Internal method to remove from a subtree.106. * @param x the item to remove.107. * @param t the node that roots the tree.108. * @return the new root.109. */110. private BinaryNode remove( Comparable x, BinaryNode t )111. {112. if( t == null )113. return t; // Item not found; do nothing114. if( x.compareTo( t.element ) < 0 )115. t.left = remove( x, t.left );116. else if( x.compareTo( t.element ) > 0 )117. t.right = remove( x, t.right );118. else if( t.left != null && t.right != null ) // Two children119. {120. t.element = findMin( t.right ).element;121. t.right = remove( t.element, t.right );122. }123. else124. t = ( t.left != null ) ? t.left : t.right;125. return t;126. }
127. /**128. * Internal method to find the smallest item in a subtree.129. * @param t the node that roots the tree.130. * @return node containing the smallest item.131. */132. private BinaryNode findMin( BinaryNode t )133. {134. if( t == null )135. return null;136. else if( t.left == null )137. return t;138. return findMin( t.left );139. }
140. /**141. * Internal method to find the largest item in a subtree.142. * @param t the node that roots the tree.143. * @return node containing the largest item.144. */145. private BinaryNode findMax( BinaryNode t )146. {147. if( t != null )148. while( t.right != null )149. t = t.right;
150. return t;151. }
152. /**153. * Internal method to find an item in a subtree.154. * @param x is item to search for.155. * @param t the node that roots the tree.156. * @return node containing the matched item.157. */158. private BinaryNode find( Comparable x, BinaryNode t )159. {160. if( t == null )161. return null;162. if( x.compareTo( t.element ) < 0 )163. return find( x, t.left );164. else if( x.compareTo( t.element ) > 0 )165. return find( x, t.right );166. else167. return t; // Match168. }
169. /**170. * Internal method to print a subtree in sorted order.171. * @param t the node that roots the tree.172. */173. private void printTree( BinaryNode t )174. {175. if( t != null )176. {177. printTree( t.left );178. System.out.println( t.element );179. printTree( t.right );180. }181. }
182. // Test program
183. public static void main( String [ ] args )
184. {
185. BinarySearchTree t = new BinarySearchTree( );
186. final int NUMS = 4000;
187. final int GAP = 37;
188. System.out.println( "Checking... (no more output means success)" );
189. for( int i = GAP; i != 0; i = ( i + GAP ) % NUMS )
190. t.insert( new MyInteger( i ) );
191. for( int i = 1; i < NUMS; i+= 2 )
192. t.remove( new MyInteger( i ) );
193.if( NUMS < 40 )194. t.printTree( );195. if( ((MyInteger)(t.findMin( ))).intValue( ) != 2 ||196. ((MyInteger)(t.findMax( ))).intValue( ) != NUMS - 2 )197. System.out.println( "FindMin or FindMax error!" );
198. for( int i = 2; i < NUMS; i+=2 )199. if( ((MyInteger)(t.find( new MyInteger( i ) ))).intValue( ) != i )200. System.out.println( "Find error1!" );
201. for( int i = 1; i < NUMS; i+=2 )202. {203. if( t.find( new MyInteger( i ) ) != null )204. System.out.println( "Find error2!" );205. }206. }207. }