Download presentation
Presentation is loading. Please wait.
Published byLawrence Brooks Modified over 9 years ago
1
1 Binary Trees Binary Trees Binary Search Trees Binary Search Trees CSE 30331 Lecture 13 –Trees
2
2 Reading Binary Trees Ford: Ch 10
3
3 Tree Structures President-CEO Production Manager Sales Manager Shipping Supervisor Personnel Manager Warehouse Supervisor Purchasing Supervisor HIERARCHICAL TREE STRUCTURE
4
4 Tree Structures
5
5
6
6 Tree Terminology Node – location containing value(s) Parent – node 1 link above “here” in tree Child – node 1 link below “here” in tree Root – top (first) node in tree Leaf – A node without any children Interior node – any non-leaf node Ancestor – any node on a path between root and “here” Descendent – any node reachable by a path from “here” downward in tree Level – number of links traversed from root to “here” Height (depth) – length of longest path from root to any leaf Subtree – Any node (chosen as root) along with all of its descendents
7
7 Tree Node Level and Path Length
8
8 Binary Tree Definition A binary tree T is a finite set of nodes with one of the following properties: (a) T has no nodes (it is the empty tree). (b) The set consists of … a root R a left subtree T L a right subtreeT R.
9
9 Samples of Binary Trees
10
10 Tree Node Level and Path Length – Depth Discussion
11
11 Tree Node Level and Path Length – Depth Discussion A E D C B G F Complete Tree (Depth 2) Also a full binary tree. Contains maximum number of leaves
12
12 Tree Node Level and Path Length – Depth Discussion
13
13 Tree Node Level and Path Length – Depth Discussion
14
14 Binary Tree Nodes
15
15 Tree Node Class template class tnode { public: // public data simplifies building class functions T nodeValue; tnode *left, *right; // default constructor. data not initialized tnode() {} // initialize the data members tnode (const T& item, tnode *lptr = NULL, tnode *rptr = NULL) : nodeValue(item), left(lptr), right(rptr) {} };
16
16 Tree Traversals A F H E D C B I Tree A Size 9 Depth 3 G Inorder: D B H E I A F C G Postorder: D H I E B F G C A Preoder: A B D E H I C F G Level-Order: A B C D E F G H I
17
17 Inorder Traversal Algorithm (1) traverse left subtree (2) process root (3) traverse right subtree // version to output values in tree “inorder” template void inorderOutput(tnode *t, const string& separator = " ") { if (t != NULL) { inorderOutput(t->left, separator);// descend left cout nodeValue << separator;// output the node inorderOutput(t->right, separator);// descend right }
18
18 Postorder Traversal Algorithm (1) traverse left subtree (2) traverse right subtree (3) process root // version to output values in tree “postorder” template void postorderOutput(tnode *t, const string& separator = " ") { if (t != NULL) { postorderOutput(t->left, separator);// descend left postorderOutput(t->right, separator);// descend right cout nodeValue << separator; // output the node }
19
19 Preorder Traversal Algorithm (1) process root (2) traverse left subtree (3) traverse right subtree // version to output values in tree “preorder” template void preorderOutput(tnode *t, const string& separator = " ") { if (t != NULL) { cout nodeValue << separator; // output the node postorderOutput(t->left, separator);// descend left postorderOutput(t->right, separator);// descend right }
20
20 Level-order traversal Similar to breadth-first search Traverses each level of the tree, in turn, from left to right Algorithm Push root on queue While queue not empty pop node from queue process node push left and right child of node onto queue
21
21 Level-order Traversal template void levelorderOutput(tnode *t, const string& separator = " ") { // store siblings of each node in a queue so that they are // after parent, and in order for next level of tree queue *> q; tnode *p; q.push(t); // start by pushing root (t) onto queue while(!q.empty()) { p = q.front(); // process front queue node q.pop(); cout nodeValue << separator; if(p->left != NULL) q.push(p->left); // push left child in queue if(p->right != NULL) q.push(p->right); // push right child on queue }
22
22 Node Density Full Tree (to depth k, or level k) 2 k+1 -1 nodes 2 k - 1 interior nodes 2 k leaves Complete Tree with n nodes depth is log 2 n Node count inequality 2 k <= n < 2 k+1 leads to k <= log 2 n < k+1
23
23 Counting Leaves Algorithm (different from text) if tree is empty return 0 else if root has no children return 1 else return leaves(T L ) + leaves(T R )
24
24 Counting Leaves template int countLeaf (tnode *t) { if (t == NULL) return 0; else if (t != NULL) { // if t is a leaf node (no children), it counts. if (t->left == NULL && t->right == NULL) return 1; return (countLeaf(t->left + countLeaf(t->right); }
25
25 Tree Depth (Height) Tree height is 1 + MAX(depth(T L ),depth(T R )) Algorithm If tree is empty return -1 else return 1 + MAX(depth(T L ),depth(T R ))
26
26 Depth (Height) int depth (tnode *t) { int depthLeft, depthRight, depthval; if (t == NULL) depthval = -1; // depth of an empty tree is -1 else { depthLeft = depth(t->left); depthRight = depth(t->right); // depth is 1 + maximum subtree depth depthval = 1 + (depthLeft > depthRight ? depthLeft : depthRight); } return depthval; }
27
27 Deleting a tree Algorithm if tree not empty delete both subtrees delete root template void deleteTree(tnode *t) { // postorder delete left and right subtrees of t // and then delete node t if (t != NULL) { deleteTree(t->left); deleteTree(t->right); delete t; }
28
28 Binary Search Tree Definition A binary search tree T is (a) a binary tree, and (b) each and every internal node R and its children (C L and C R ), if they exist, have values such that (value C L < value R <= value C R )
29
29 Binary Search Trees
30
30 CLASS stree Constructors “d_stree.h” stree(); Create an empty search tree. stree(T *first, T *last); Create a search tree with the elements from the pointer range [first, last). CLASS stree Opertions “d_stree.h” void displayTree(int maxCharacters); Display the search tree. The maximum number of characters needed to output a node value is maxCharacters. bool empty(); Return true if the tree is empty and false otherwise.
31
31 CLASS stree Opertions “d_stree.h” int erase(const T& item); Search the tree and remove item, if it is present; otherwise, take no action. Return the number of elements removed. Postcondition: If item is located in the tree, the size of the tree decreases by 1. void erase(iterator pos); Erase the item pointed to the iterator pos. Precondition:The tree is not empty and pos points to an item in the tree. If the iterator is invalid, the function throws the referenceError exception. Postcondition: The tree size decreases by 1.
32
32 CLASS stree Opertions “d_stree.h” void erase(iterator first, iterator last); Remove all items in the iterator range [first, last). Precondition: The tree is not empty. If empty, the function throws the underflowError exception. Postcondition: The size of the tree decreases by the number of items in the range. iterator find(const T& item); Search the tree by comparing item with the data values in a path of nodes from the root of the tree. If a match occurs, return an iterator pointing to the matching value in the tree. If item is not in the tree, return the iterator value end().
33
33 CLASS stree Opertions “d_stree.h” pair insert(const T& item); If item is not in the tree, insert it and return an iterator- bool pair where the iterator is the location of the new element and the Boolean value is true. If item is already in the tree, return the pair where the iterator locates the existing item and the Boolean value is false. Postcondition: The size of the tree is increased by 1 if item is not present in the tree. int size(); Return the number of elements in the tree.
34
34 What is a pair? Examples later. The pair template data type is defined in the header file It has two public members first and second The insert(item) function returns a pair containing an iterator and a bool first is the iterator and it indicates the node in the Stree containing the item second is a bool indicating whether the node was actually added to the tree (true) or was already there (false) So, the pair gives a function a way to return two values instead of one
35
35 STree Node Class template class stnode { public: // public data simplifies building class functions T nodeValue; stnode *left, *right, *parent; // default constructor. data not initialized tnode() {} // initialize the data members stnode (const T& item, stnode *lptr = NULL, stnode *rptr = NULL, stnode *pptr = NULL) : nodeValue(item), left(lptr), right(rptr), parent(pptr) {} };
36
36 Stree Iterators Perform INORDER traversals of tree Iterator and const_iterator are implemented as contained classes within Stree class See “d_stree.h” and d_siter.h” Iterator is a two part object with pointer to root of Stree and to current Stnode (see below) private: stnode *nodePtr; // current location in tree stree *tree; // the tree // used to construct an iterator return value // from an stnode pointer iterator (stnode *p, stree *t) : nodePtr(p), tree(t) {}
37
37 Locating value 37 in a BST CurrentNode Action Root = 50 Compare item = 37 and 50 37 < 50, move to the left subtree Node = 30 Compare item = 37 and 30 37 > 30, move to the right subtree Node = 35 Compare item = 37 and 35 37 > 35, move to the right subtree Node = 37 Compare item = 37 and 37. Item found.
38
38 FindNode() function template stnode *stree ::findNode(const T& item) const { // cycle t through the tree starting with root stnode *t = root; // terminate on on empty subtree while(t != NULL && (item != t->nodeValue)) if (item nodeValue) t = t->left; else t = t->right; // return pointer to node; NULL if not found return t; }
39
39 Stree find() function template stree ::iterator stree ::find(const T& item) { stnode *curr; // search tree for item curr = findNode (item); // if item found, return iterator with value curr; // otherwise, return end() if (curr != NULL) return iterator(curr, this); else return end(); }
40
40 Inserting into search tree All insertions are as LEAVES Algorithm if tree is empty insert new node here else if new value == node value return without inserting else if new value < node value insert in left subtree else if new value > node value insert in right subtree
41
41 Insert() function template pair ::iterator, bool> stree ::insert(const T& item) { stnode *t = root, *parent = NULL, *newNode; while(t != NULL) { parent = t; if (item == t->nodeValue) // found a match return pair (iterator(t,this),false); else if (item nodeValue) t = t->left; else t = t->right; } newNode = getSTNode(item,NULL,NULL,parent); if (parent == NULL) // insert as root node root = newNode; else if (item nodeValue) // insert as left child parent->left = newNode; else // insert as right child parent->right = newNode; treeSize++; return pair (iterator(newNode, this), true); }
42
42 Insertion: 1 st of 3 steps The function begins at the root node and compares item 32 with the root value 25. Since 32 > 25, we traverse the right subtree and look at node 35.
43
43 Insertion: 2 nd of 3 steps Considering 35 to be the root of its own subtree, we compare item 32 with 35 and traverse the left subtree of 35.
44
44 Insertion: 3 rd of 3 steps Create a leaf node with data value 32, and insert the new node as the left child of node 35. newNode = getSTNode(item,NULL,NULL,parent); parent->left = newNode;
45
45 Deleting a node Three cases (1) node that is a leaf Just delete it (2) node with single child Delete node and replace it in tree with its child (3) node with two children Find inorder successor This will be a leaf or a node with only a Right child Swap value of node and its inorder successor Delete successor node (now case 1 or 2)
46
46 Erase() function template void stree ::erase(iterator pos) { // dNodePtr = pointer to node D that is deleted // pNodePtr = pointer to parent P of node D // rNodePtr = pointer to node R that replaces D stnode *dNodePtr = pos.nodePtr, *pNodePtr, *rNodePtr; if (treeSize == 0) throw underflowError("stree erase(): tree is empty"); if (dNodePtr == NULL) throw referenceError("stree erase(): invalid iterator"); // assign pNodePtr the address of P pNodePtr = dNodePtr->parent; // now determine which case deletion we have // leaf node or node with single child (easy cases) // or node with 2 children (hard case) // continued....
47
47 Erase() // If D has a NULL pointer, the // replacement node is the other child if (dNodePtr->left == NULL || dNodePtr->right == NULL) { if (dNodePtr->right == NULL) rNodePtr = dNodePtr->left; // replacement: left child else rNodePtr = dNodePtr->right; // replacement: right child if (rNodePtr != NULL) // the parent of R is now the parent of D rNodePtr->parent = pNodePtr; } else // node has two children { // find inorder successor, right & then all the way left stnode *pOfRNodePtr = dNodePtr; // parent of successor rNodePtr = dNodePtr->right; // step right while(rNodePtr->left != NULL) { pOfRNodePtr = rNodePtr; rNodePtr = rNodePtr->left; // step left... }
48
48 Erase() if (pOfRNodePtr == dNodePtr) { // right child of deleted node is the replacement. rNodePtr->left = dNodePtr->left; rNodePtr->parent = pNodePtr; dNodePtr->left->parent = rNodePtr; } else { // we moved at least one node down a left branch // of the right child of D. link right subtree of R // as left subtree of parent of R pOfRNodePtr->left = rNodePtr->right; if (rNodePtr->right != NULL) rNodePtr->right->parent = pOfRNodePtr; // link R to D’s children and parent rNodePtr->left = dNodePtr->left; rNodePtr->right = dNodePtr->right; rNodePtr->parent = pNodePtr; rNodePtr->left->parent = rNodePtr; rNodePtr->right->parent = rNodePtr; }
49
49 Erase() // finally, connect R as correct child of parent node of D // if deleting the root node. assign new root if (pNodePtr == NULL) root = rNodePtr; // else attach R as correct child of P else if (dNodePtr->nodeValue nodeValue) pNodePtr->left = rNodePtr; else pNodePtr->right = rNodePtr; // delete the node from memory and decrement tree size delete dNodePtr; treeSize--; }
50
50 Removing an Item From a Binary Tree
51
51 Removing an Item From a Binary Tree
52
52 Removing an Item From a Binary Tree
53
53 Removing an Item From a Binary Tree
54
54 Removing an Item From a Binary Tree
55
55 Removing an Item From a Binary Tree
56
56 Simple Application -- Removing Duplicates Since a binary search tree does not insert duplicates, a vector can be purged of duplicates by … For each element in vector Insert element in binary search tree Clear vector For each element in binary search tree Append element to vector Clear binary search tree If the search tree is traversed “inorder” this results in a sort of the vector as well
57
57 Using Binary Search Trees Application: Removing Duplicates
58
58 Stree begin() and end() template stree ::iterator stree ::begin() { stnode *curr = root; // if the tree is not empty, the first node // inorder is the farthest node left from root if (curr != NULL) while (curr->left != NULL) curr = curr->left; // build return value using private constructor return iterator(curr, this); } template stree ::iterator stree ::end() { // end indicated by iterator with NULL stnode pointer return iterator(NULL, this); }
59
59 Stree iterator preincrement operator++ iterator& operator++ () // preincrement. move forward inorder { stnode *p; if (nodePtr == NULL) // ++ from end() { nodePtr = tree->root; // start at root if (nodePtr == NULL) throw underflowError("stree iter op++ (): t empty"); // move to smallest value in tree, 1st node inorder while (nodePtr->left != NULL) nodePtr = nodePtr->left; } else if (nodePtr->right != NULL) { // find successor { nodePtr = nodePtr->right; // step right while (nodePtr->left != NULL) nodePtr = nodePtr->left; // go all the way left } else // move up the tree, looking for a parent having { // *nodePtr is left child p = nodePtr->parent; while (p != NULL && nodePtr == p->right) { nodePtr = p; p = p->parent; } nodePtr = p; // now, either p is NULL or *p is the successor } return *this; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.