Docstoc

Tree

Document Sample
Tree Powered By Docstoc
					Tree
Basic characteristic

               1.




     2.        5.   6.



3.        4.             7.
• 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! ->        1
  Data               Link to next sibling.
                                                 2       5   6


    Link to its first child.                 3       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….
          Preorder result is 1,2,3,4,5,6,7
                                                       First to pick
                                     1.


       Second, this                                               4th, this subtree
       subtree
                           2.        5.           6.
                                                                        Inside, it is
Inside, we
                                                                        also preorder.
also view it
with preorder.
                      3.        4.                       7.



                                          Third
• postorder
  – View all subtrees, then the root.
  – Inside each subtree, use postorder.
  – The postorder result of our example is 3,4,2,5,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) 3,2,4,1,6,7
         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. -> 1,2,5,6,3,4,7
   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
                            +               -


                    a           *       d       e


                        b           c
    breadth-first implementation(2)
•       When we look at the root, we record itsildren into next level queue. Therefore, at
        this stage, next level queue has + and –.
•       this level queue = next level queue; clear next level queue
•       Inspect this level queue.
    –       Find +: Now we insert the children of + into next level queue
    –       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 this 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).
full binary tree or perfectly balanced
                  tree
• A complete triangle, no missing leaf.
                 complete tree
• Full up to the level before the highest
  level.
• At the highest level, leaves must fill from
  left to right.        A


                     N            E


                 T       O    X

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
                two-tree
• Must be empty tree or
• All non-leaf must have 2 branches.
         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:
                                        n(t )  1
                           leaves(t ) 
                                          2.0

                            n(t )  1
                                       2 height ( t )
                              2.0
                                                                n (t )  1
If t is a two-tree, then                    leaves (t ) 
                                                                   2.0
                           n (t )  1
 If    leaves (t )                         Then t is definitely a two-tree.
                              2.0
                     If t is a full tree,        n (t )  1
                                                             2height (t )
                                                    2.0
     n (t )  1
If               2height (t )   , then t is a full tree
        2.0
                              n(t )  1
 Proving         leaves(t ) 
                                2.0
base case is when our tree has only its root.

             leaves (t )  1
              n(t)  1
                           1
                2.0
               Which is true.

inductive case is when our tree has height h. Let
                         n(t )  1
            leaves(t ) 
                           2.0
                                                                n(t )  1
We must prove that when t has height = h+1, then leaves(t ) 
                                                                  2.0
 leaves(t)  leaves(leftsubtree(t  leaves(rightsubtree(t))
                                ))
           n(leftsubtree(t)) 1 n(rightsubtree(t)) 1
                              
                   2.0                  2.0
We know that:
     n(t)  n(leftsubtree(t))  n(rightsubtree(t)) 1
     We can substitute n(t) into our equation.

                                   n(t )  1
                      leaves(t ) 
                                     2.0
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

           E (t )  (k / 2) log 2 k 
          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

                 5           11


         2           6            14


             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 BinaryNode
2.    {
3.         // Constructors
4.      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 routines
15.       Comparable element;         // The data in the node
16.       BinaryNode left;       // Left child
17.       BinaryNode right;       // Right child
18.   }
// 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 BinarySearchTree
2.   {
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.       else
75.           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*/        else
101./* 8*/            ; // Duplicate; do nothing
102./* 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 nothing
114.             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 children
119.             {
120.                 t.element = findMin( t.right ).element;
121.                 t.right = remove( t.element, t.right );
122.             }
123.             else
124.                 t = ( t.left != null ) ? t.left : t.right;
125.             return t;
126.         }
     X                y




         y                y


Replacing a deleted element with
  the smallest value of its right
            subtree.
        x              y

            y




Replacing a deleted node with its
subtree. This happens when the
  node only has one subtree.
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.       else
167.           return t; // Match
168.   }
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.   }

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:8
posted:8/7/2012
language:English
pages:42