520 likes | 625 Views
Explore the concepts of binary trees, linear search, and binary search trees with examples and explanations. Learn about tree terminology, tree levels, recursive definitions, and array vs. linked representations of binary trees.
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