520 likes | 616 Views
Binary Trees. Gordon College Prof. Brinton. Good O’ Linear Search. Collection of data items to be searched is organized in a list x 1 , x 2 , … x n Must assume = = and < operators defined for the type Linear search begins with item 1 continue through the list until target found
E N D
Binary Trees Gordon College Prof. Brinton
Good O’ Linear Search • Collection of data items to be searched is organized in a listx1, x2, … xn Must assume = = and < operators defined for the type • Linear search begins with item 1 • continue through the list until target found • or reach end of list Not sorted
Linear Search Vector based search function template <typename t>void LinearSearch (const vector<t> &v, const t &item, boolean &found, int &loc){ found = false; loc = 0; for ( ; ; ){ if (found || loc == v.size()) return; if (item == x[loc]) found = true; else loc++; }} usage LinearSearch(vect,num,found,loc);
Linear Search Singly-linked list based search function template <typename t>void LinearSearch (NodePointer first, const t &item, boolean &found, int &loc){ found = false; locptr = first; for ( ; ; ){ if (found || locptr == NULL) return; if (item == locptr->data) found = true; else loc++; }} In both cases, the worst case computing time is still O(n)
Binary Search Sorted vector Binary search function for vector template <typename t>void LinearSearch (const vector<t> &v, const t &item, boolean &found, int &loc) { found = false; int first = 0; last = v.size() - 1; for ( ; ; ){ if (found || first > last) return; loc = (first + last) / 2; if (item < v[loc]) last = loc + 1; else if (item > v[loc]) first = loc + 1; else /* item == v[loc] */ found = true; } }
Binary Search • Usually outperforms a linear search • Disadvantage: - Only appropriate for direct access structures like vectors - not linked lists (Why?) • It is possible to use a linked structure which can be searched in a binary-like manner
13 28 35 49 62 66 80 Binary Search Tree • Consider the following ordered list of integers • Examine middle element • Examine left, right sublist (maintain pointers) • (Recursively) examine left, right sublists
Binary Search Tree • Redraw the previous structure so that it has a treelike shape – a binary tree
Trees • A data structure which consists of • a finite set of elements called nodes or vertices • a finite set of directed arcs which connect the nodes • If the tree is nonempty • one of the nodes (the root) has no incoming arc • every other node can be reached by following a unique sequence of consecutive arcs
Root node • Children of the parent (3) • Siblings to each other Leaf nodes Trees • Tree terminology Interior nodes
Trees • More Tree Terms • The depth of a node n is the length of the path from the root to the node. • The height of a tree is the depth of its furthest leaf. • Siblings are nodes that share the same parent node. • If a path exists from node p to node q, where node p is closer to the root node than q, then p is an ancestor of q and q is a descendant of p. • The size of a node is the number of descendants it has including itself. • In-degree of a vertex is the number of edges arriving at that vertex. • Out-degree of a vertex is the number of edges leaving that vertex. Each node in tree is the root of a Subtree Recursive?
L A B C D E F G H Tree Levels e v e l : 0 L e v e l : 1 L e v e l : 2 L e v e l : 3
Binary Trees • Each node has at most two children • Useful in modeling processes where • a comparison or experiment has exactly two possible outcomes • the test is performed repeatedly • Examples • multiple coin tosses • Expert systems (yes/no questions) • encoding/decoding messages in dots and dashes such as Morse code • Expression tree (compiler generates)
Recursive Definition Binary Trees A binary tree T is a finite set of nodes with one of the following properties: • T is a tree if the set of nodes is empty. (An empty tree is a tree.) • The set consists of a root, R, and exactly two distinct binary trees, the left subtree TL and the right subtree TR. The nodes in T consist of node R and all the nodes in TL and TR.
Binary Trees A B D E Right Subtree G H Left Subtree
Binary Trees A B C D E G F H K I N o n - C o m p l e t e T r e e ( D e p t h 3 ) N o d e s a t l e v e l 3 d o n o t o c c u y l e f t m o s t p o s i t i o n s p
A B C D E G F H I J A B C D E G F Tree Density Total nodes (for top levels) 2d - 1 23-1 = 7 Additional Nodes 3 A B C If totally complete tree: 2d - 1 + 2d D complete tree: 2d - 1 + 1 = 2d
A B C D E G F Tree Density A B C If totally complete tree: 2d - 1 + 2d D complete tree: 2d - 1 + 1 = 2d N nodes of complete tree satisfy inequality 2d <= n <= 2d+1 - 1 < 2d+1 d <= log2 n < d+1 Height (depth) of n node tree: int (log2 n)
Array Representation of Binary Trees • Store the ith node in the ith location of the array
Array Representation of Binary Trees • Works OK for complete trees, not for sparse trees
Linked Representation of Binary Trees • Pros: • Uses space more efficiently • Provides additional flexibility • Con: more overhead • Each node has two links • one to the left child of the node • one to the right child of the node • if no child node exists for a node, the link is set to NULL
Linked Representation of Binary Trees • Example
Inductive step Binary Trees as Recursive Data Structures • A binary tree is either empty … or • Consists of • a node called the root • root has pointers to two disjoint binary (sub)trees called … • right (sub)tree • left (sub)tree Anchor Which is either empty … or … Which is either empty … or …
The "anchor" The inductive step Tree Traversal is Recursive If the binary tree is empty thendo nothing Else N: Visit the root, process dataL: Traverse the left subtreeR: Traverse the right subtree
Traversal Order Three possibilities for inductive step: • Left subtree, Node, Right subtreethe inorder traversal • Node, Left subtree, Right subtreethe preorder traversal • Left subtree, Right subtree, Nodethe postorder traversal
Traversal Order • Given expressionA – B * C + D • Represent each operand as • The child of a parent node • Parent node,representing the corresponding operator
Traversal Order • Inorder traversal produces infix expressionA – B * C + D • Preorder traversal produces the prefix expression+ - A * B C D • Postorder traversal produces the postfix or RPN expressionA B C * - D +
Traversal Order • Iterative Level-Order Scan Visit + Visit - D Visit A * Visit B C How is this possible?
Traversal Order • Iterative Level-Order Scan Visit + Visit - D Visit A * Visit B C How is this possible? Use a queue as the intermediate storage device
Traversal Order • Iterative Level-Order Scan Visit + Visit - D Visit A * Visit B C Initialization Step: node<T> *root; queue<node<T> *> q; q.push(root); Iterative Step: Get node N pointer from Q (if Q empty exit) Delete a node N pointer from Q Visit the node N Push node N’s children onto Q Go to step 1
Binary Search Tree (BST) • Collection of Data Elements • binary tree • each node x, • value in left child of x value in x in right child of x • Basic operations • Construct an empty BST • Determine if BST is empty • Search BST for given item
Binary Search Tree (BST) • Basic operations (continued) • Insert a new item in the BST • Maintain the BST property • Delete an item from the BST • Maintain the BST property • Traverse the BST • Visit each node exactly once • The inordertraversal must visit the values in the nodes in ascending order
template <class elemType> class BST { private: template<class T> struct nodeType { T info; nodeType<T> *llink; nodeType<T> *rlink; }; public: bool isEmpty(); void inorderTraversal(); void preorderTraversal(); ... binaryTreeType(const binaryTreeType<elemType>& otherTree); binaryTreeType(); ~binaryTreeType();
private: nodeType<elemType> *root; void copyTree(nodeType<elemType>* &copiedTreeRoot, nodeType<elemType>* otherTreeRoot); ... void destroy(nodeType<elemType>* &p); void inorder(nodeType<elemType> *p); void preorder(nodeType<elemType> *p); };
BST Traversals Public method voidinorderTraversal(); Private recursive auxillary method template<class elemType> void binaryTreeType<elemType>::inorder(nodeType<elemType> *p) { if(p != NULL) { inorder(p->llink); cout<<p->info<<" "; inorder(p->rlink); } }
BST Leaf Count Create a method that returns leaf count…
BST Leaf Count intbinaryTreeType<elemType>::treeLeavesCount() { return leavesCount(root); } template<class elemType> int binaryTreeType<elemType>::leavesCount(nodeType<elemType> *p) { if (p != NULL) { if (p->llink == NULL && p->rlink == NULL) return 1; else return (leavesCount(p->llink) + leavesCount(p->rlink)); } else return 0; }
BST Searches • Search begins at root • If that is desired item, done • If item is less, move downleft subtree • If item searched for is greater, move down right subtree • If item is not found, we will run into an empty subtree
BST Searches • Search begins at root • If that is desired item, done • If item is less, move downleft subtree • If item searched for is greater, move down right subtree • If item is not found, we will run into an empty subtree Remember: N nodes of complete tree satisfy inequality 2d <= n <= 2d+1 - 1 < 2d+1 d <= log2 n < d+1 d is levels Height of n node tree: int (log2 n) Max compares for complete tree: (int) log2 n + 1
R Iterative Inserting into a BST • Insert function – Letter R • Uses modified version of search to locate insertion location or already existing item • Pointer parent trails search pointer locptr, keeps track of parent node • Thus new node can be attached to BST in proper place
30 15 70 10 (Recursive) Inserting into a BST • Insert function • Base case • Root pointer = null (empty) • Create new node and return pointer to this new tree • Recursive case • If root pointer != null (not empty) • Compare new item to root’s item • If item > root item then insert into right subtree (insert root->rllink) • If item < root item then insert into left subtree • If item = root item then don’t insert
30 15 70 10 (Recursive) Inserting into a BST
Recursive Deletion Three possible cases to delete a node, x, from a BST 1. The node, x, is a leaf
Recursive Deletion 2. The node, x has one child
Delete node pointed to by xSucc as described for cases 1 and 2 K Replace contents of x with inorder successor Recursive Deletion • x has two children
Problem of Lopsidedness • Tree can be balanced • each node except leaves has exactly 2 child nodes
Problem of Lopsidedness • Trees can be unbalanced • not all nodes have exactly 2 child nodes
Problem of Lopsidedness • Trees can be totally lopsided • Suppose each node has a right child only • Degenerates into a linked list Processing time affected by "shape" of tree
Threaded Binary Search Trees • Use special links in a BST • These threads provide efficient nonrecursivetraversal algorithms • Build a run-time stack into the tree for recursive calls
Threaded Binary Search Trees • Note the sequence of nodes visited • Left to right • A right threaded BST • Whenever a node, x, with null right pointer is encountered, replace right link with thread to inorder successor of x • Inorder successor of x is its parent if x is a left child • Otherwise it is nearest ancestor of x that contains x in its left subtree