Title: Binary Search Tree
1CSE 331 Lecture 16
Chapter 10 Binary Search Tree Locating a
Node Inserting a Node Removing a Leaf Removing a
non-leaf 1 child 2 children
BSTree Iterator Begin End Operator Operator
Summary Slides Demo tsimND Discuss Traffic
Simulation
2STree Node Class
- template lttypename Tgt
- class stnode
-
- public
- // public data simplifies building class
functions - T nodeValue
- stnodeltTgt left, right, parent
- // default constructor. data not
initialized - tnode()
-
- // initialize the data members
- stnode (const T item, stnodeltTgt lptr
NULL, - stnodeltTgt rptr NULL, stnodeltTgt
pptr NULL) - nodeValue(item), left(lptr), right(rptr),
parent(pptr) -
3Binary Search Tree Definition
- A binary search tree T is
- (a) a binary tree, and
- (b) each and every internal node R and its
children (CL and CR), if they exist, have values
such that valueCL lt valueR lt valueCR
4Binary Search Trees
5(No Transcript)
6(No Transcript)
7(No Transcript)
8(No Transcript)
9FindNode() function
- template lttypename Tgt
- stnodeltTgt streeltTgtfindNode(const T item)
const -
- // cycle t through the tree starting with root
- stnodeltTgt t root
- // terminate on on empty subtree
- while(t ! NULL !(item t-gtnodeValue))
- if (item lt t-gtnodeValue)
- t t-gtleft
- else
- t t-gtright
- // return pointer to node NULL if not found
- return t
10Stree find() function
- template lttypename Tgt
- streeltTgtiterator streeltTgtfind(const T item)
-
- stnodeltTgt curr
- // search tree for item
- curr findNode (item)
- // if item found, return iterator with value
current - // otherwise, return end()
- if (curr ! NULL)
- return iterator(curr, this)
- else
- return end()
-
11Inserting into search tree
- All insertions are as LEAVES
- If tree is empty
- insert new node here
- Else if new value node value
- return without inserting
- Else if new value lt node value
- insert in left subtree
- Else if new value gt node value
- insert in right subtree
12Insert() function
- template lttypename Tgt
- pairltstreeltTgtiterator, boolgt streeltTgtinsert(co
nst T item) -
- stnodeltTgt t root, parent NULL, newNode
- while(t ! NULL)
- parent t
- if (item t-gtnodeValue) // found a
match - return pairltiterator, boolgt
(iterator(t,this),false) - else if (item lt t-gtnodeValue)
- t t-gtleft
- else
- t t-gtright
-
- newNode getSTNode(item,NULL,NULL,parent)
- if (parent NULL) // insert as
root node - root newNode
- else if (item lt parent-gtnodeValue) // insert as
left child - parent-gtleft newNode
- else // insert as
right child
13Insertion 1st of 3 steps
1)- The function begins at the root node and
compares item 32 with the root value 25. Since
32 gt 25, we traverse the right subtree and
look at node 35.
14Insertion 2nd of 3 steps
2)- Considering 35 to be the root of its own
subtree, we compare item 32 with 35 and
traverse the left subtree of 35.
15Insertion 3rd of 3 steps
1)- Create a leaf node with data value 32. Insert
the new node as the left child of node
35. newNode getSTNode(item,NULL,NULL,parent)
parent-gtleft newNode
16Deleting 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)
17Erase() function
- template lttypename Tgt
- void streeltTgterase(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 - stnodeltTgt 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-gtparent
- // now determine which case deletion we have
- // leaf node or node with single child (easy
cases)
18Erase()
- // If D has a NULL pointer, the
- // replacement node is the other child
- if (dNodePtr-gtleft NULL dNodePtr-gtright
NULL) -
- if (dNodePtr-gtright NULL)
- rNodePtr dNodePtr-gtleft //
replacement left child - else
- rNodePtr dNodePtr-gtright//
replacement right child - if (rNodePtr ! NULL)
- // the parent of R is now the parent of
D - rNodePtr-gtparent pNodePtr
-
- else // node has two children
-
- // find inorder successor, right then all
the way left - stnodeltTgt pOfRNodePtr dNodePtr //
parent of successor - rNodePtr dNodePtr-gtright // step
right - while(rNodePtr-gtleft ! NULL)
19Erase()
- if (pOfRNodePtr dNodePtr)
- // right child of deleted node is the
replacement. - rNodePtr-gtleft dNodePtr-gtleft
- rNodePtr-gtparent pNodePtr
- dNodePtr-gtleft-gtparent 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-gtleft rNodePtr-gtright
- if (rNodePtr-gtright ! NULL)
- rNodePtr-gtright-gtparent
pOfRNodePtr - // link R to Ds children and parent
- rNodePtr-gtleft dNodePtr-gtleft
- rNodePtr-gtright dNodePtr-gtright
- rNodePtr-gtparent pNodePtr
- rNodePtr-gtleft-gtparent rNodePtr
- rNodePtr-gtright-gtparent rNodePtr
20Erase()
-
- // 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-gtnodeValue lt
pNodePtr-gtnodeValue) - pNodePtr-gtleft rNodePtr
- else
- pNodePtr-gtright rNodePtr
- // delete the node from memory and decrement
tree size - delete dNodePtr
- treeSize--
-
21Removing an Item From a Binary Tree
22Removing an Item From a Binary Tree
23Removing an Item From a Binary Tree
24Removing an Item From a Binary Tree
25Removing an Item From a Binary Tree
26Removing an Item From a Binary Tree
27Stree 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
- stnodeltTgt nodePtr // current location in
tree - streeltTgt tree // the tree
- // used to construct an iterator return value
- // from an stnode pointer
- iterator (stnodeltTgt p, streeltTgt t)
- nodePtr(p), tree(t)
-
28Stree begin() function
- template lttypename Tgt
- streeltTgtiterator streeltTgtbegin()
-
- stnodeltTgt curr root
- // if the tree is not empty, the first node
- // inorder is the farthest node left from root
- if (curr ! NULL)
- while (curr-gtleft ! NULL)
- curr curr-gtleft
- // build return value using private constructor
- return iterator(curr, this)
29Stree end() function
- template lttypename Tgt
- streeltTgtiterator streeltTgtend()
-
- // end indicated by iterator with NULL stnode
pointer - return iterator(NULL, this)
-
30Siter operator() - preincrement
- iterator operator () // preincrement. move
forward inorder - stnodeltTgt p
- if (nodePtr NULL) // from end()
- nodePtr tree-gtroot // start at root
- if (nodePtr NULL)
- throw underflowError("stree iter op
() t empty") - // move to smallest value in tree, 1st node
inorder - while (nodePtr-gtleft ! NULL)
- nodePtr nodePtr-gtleft
-
- else if (nodePtr-gtright ! NULL) // find
successor - nodePtr nodePtr-gtright // step
right - while (nodePtr-gtleft ! NULL)
- nodePtr nodePtr-gtleft // go all
the way left -
- else // move up the tree, looking for a
parent having - // nodePtr is left child
- p nodePtr-gtparent
- while (p ! NULL nodePtr p-gtright)
31Siter operator(int) - postincrement
- iterator operator (int) // postincrement
-
- // save current iterator
- iterator tmp this
- // move myself forward to the next tree node
- this
- // return the previous value
- return tmp
-
32Summary Slide 1
- trees - hierarchical structures that place
elements in nodes along branches that
originate from a root. - Nodes in a tree are
subdivided into levels in which the topmost
level holds the root node. - Any node in a
tree may have multiple successors at the
next level. Hence a tree is a non-linear
structure. - Tree terminology with which you
should be familiar parent child
descendents leaf node interior node
subtree.
33Summary Slide 2
- Binary Trees - Most effective as a storage
structure if it has high density - ie
data are located on relatively short paths from
the root. - A complete binary tree has
the highest possible density - an n-node
complete binary tree has depth int(log2n).
- At the other extreme, a degenerate binary tree
is equivalent to a linked list and exhibits
O(n) access times.
34Summary Slide 3
- Traversing Through a Tree - There are six
simple recursive algorithms for tree
traversal. - The most commonly used ones
are 1) inorder (LNR) 2) postorder
(LRN) 3) preorder (NLR). - Another technique
is to move left to right from level to
level. - This algorithm is iterative, and
its implementation involves using a queue.
35Summary Slide 4
- A binary search tree stores data by value
instead of position - It is an example of an
associative container. - The simple
rules return lt go
left gt go right until finding a
NULL subtree make it easy to build a binary
search tree that does not allow duplicate
values.
36Summary Slide 5
- The insertion algorithm can be used to define
the path to locate a data value in the
tree. - The removal of an item from a binary
search tree is more difficult and involves
finding a replacement node among the remaining
values.
37Summary Slide 6
- Iterators traverse the Stree INORDER. Stree
functions begin() and end() set initial iterator
values, while and operators are iterator
functions. - Iterators may be implemented as
imbedded classes within the BStree class.