Date post: | 13-Jan-2016 |
Category: |
Documents |
Upload: | august-adams |
View: | 214 times |
Download: | 0 times |
BINARY SEARCH TREE
Binary Trees
A binary tree is a tree in which no node can have more than two children.
In this case we can keep direct links to the children:
struct TreeNode{ Object element; TreeNode *left_child; TreeNode *right_child;};
Binary Trees: Recursive Definition
ROOT OF TREE T
T1 T2
SUBTREES
*left_child *right_child
Binary Search TreesAssume that each node in the tree stores an item (e.g., a word from a dictionary). These items can be ordered in some consistent manner.A binary search tree is a binary tree where, for every node X in the tree, the values of the items in its left subtree are smaller than the item in X, and the values of the items in its right subtree are larger than the item in X.
Binary Search Tree
ROOT OF TREE T
T1 T2
SUBTREES
*left_child *right_childX
All nodes in T1 havevalues < X.
All nodes in T2 havevalues > X.
Binary Search Trees in C++
We will use two classes:The class BinaryNode simply constructs individual nodes in the tree.The class BinarySearchTree maintains a pointer to the root of the binary search tree and includes methods for inserting and removing nodes.
Binary Search Trees in C++
element, *left, *right
constructor method
The BinaryNode Class class BinaryNode
{
int element;
BinaryNode *left;
BinaryNode *right;
BinaryNode (const int & el,
BinaryNode *lt, BinaryNode *rt)
: element (el), left (lt), right (rt) { }
friend class BinarySearchTree;
};
*left *right
el
Binary Search Trees in C++
*root
find/insert/remove methods
The BinarySearchTree Classclass BinarySearchTree
{
public:
explicit BinarySearchTree (const int ¬Found);
const int &find (const int &x) int;
void insert (const int &x);
void remove (const int &x);
private:
BinaryNode *root;
const int NOT_FOUND;
};
*left *right
el*root
Binary Search Tree Methods
The Find operation returns a pointer to the node in a tree T that has item X, or NULL if there is no such node.The Insert operation inserts a new node (with item X) into the tree T.The Remove operation removes the node (with item X) from the tree T.
The Find Operation
// Returns the element at the node
const int &elementAt (BinaryNode *t) const
{
return t == NULL ? NOT_FOUND : t element;
}
// Start the search at the root node
const int &find (const int & x) const
{
return elementAt (find (x, root));
}
element
*t
*root
The Find Operation…
BinaryNode *find (const int &x, BinaryNode *t) const
{
if ( t == NULL )
return NULL;
else if ( x < t element )
return find ( x, t left );
else if ( t element < x )
return find ( x, t right );
else
return t; // Match
}
*root
6
2
5
9
7 10
Suppose I try to find thenode with 7 in it. First godown the right subtree, thengo down the left subtree.
The FindMin Operation…
BinaryNode *findMin (BinaryNode *t) const
{
if ( t == NULL )
return NULL;
else if ( t left == NULL )
return t;
return findMin (t left);
}
*root
6
2
5
9
7 10
This function returns a pointer to the node containing thesmallest element in the tree. It does so by following the leftside of the tree.
The FindMax Operation…
BinaryNode *findMax (BinaryNode *t) const
{
if ( t == NULL )
return NULL;
else if ( t right == NULL )
return t;
return findMax (t right);
}
*root
6
2
5
9
7 10
This function returns a pointer to the node containing thelargest element in the tree. It does so by following the rightside of the tree.
The Insert OperationInsertion is conceptually simple. To insert X into a tree T, proceed down the tree as you would with a find. If X is found, do nothing. Otherwise insert X at the last spot on the path that has been traversed.
*root
6
2
5
9
7 101
For example, suppose I want toinsert a 1 into this tree…
The Insert Operationvoid BinarySearchTree insert (const int &x,
BinaryNode *&t) const
{
if (t == NULL)
t = new BinaryNode (x, NULL, NULL);
else if (x < t element)
insert(x, t left);
else if( t element < x)
insert(x, t right);
else
; // Duplicate entry; do nothing
}
*root
6
2
5
9
7 10
t left
1
NULLNULL
tNote the pointer t is passedusing call by reference. In this casethis means tleft will be changed to t.
The Removal OperationIf the node to be removed is a leaf, it can be deleted immediately.If the node has one child, the node can be deleted after its parent adjusts a link to bypass the deleted node. *root
6
2
5
9
7 10
What if the 2 is deleted?
Removal…
*root
6
2
5
9
7 10
*root
6
2
5
9
7 10
t
t right
Set t = t right
Removal…
If the node to be removed has two children, the general strategy is to replace the data of this node with the smallest data of the right subtree.Then the node with the smallest data is now removed (this case is easy since this node cannot have two children).
Removal…
*root
6
2
5
9
7 101
3
4
Remove the 2 again…
*root
6
3
5
9
7 101
3
4
The Removal Operation void remove (const int &x, BinaryNode *&t) const {
if ( t == NULL ) return; // Item not found; do nothing
if ( x < t element ) remove( x, t left );
else if( t element < x ) remove( x, t right );
else if( t left != NULL && t right != NULL ) // Two children
{
t element = findMin( t right ) element;
remove( t element, t right ); }
else // One child
{
BinaryNode *oldNode = t;
t = ( t left != NULL ) ? t left : t right;
delete oldNode; }
}
Other Methods
Please see the text for the C++ destructor and copy constructors (pages 139-140).
Analysis
The running time of these operations is O(d), where d is the depth of the node containing the accessed item.What is the average depth of the nodes in a binary search tree? It depends on how well balanced the tree is.
Average Depth of Nodes10
5 20
1 8 13 34
Consider this very well-balanced binary search tree. What is thedepth of its leaf nodes?
1)(log so 122 21
0
NDN D
D
d
d
N=7
Data Order: 10, 5, 1, 8, 20, 13, 34
A Better Analysis
The analysis on the previous slide was for a particularly well-balanced binary search tree. However, not all binary search trees will be this well balanced.In particular, binary search trees are created via insertions of data. Depending on the order of the data, various trees will emerge.
Effect of Data Order4
3
2
1
Obtained if data is 4, 3, 2 1
1
2
3
4
Obtained if data is 1, 2, 3, 4
Note in these cases the average depth of nodes is about N/2, not log(N)!
Depth of Nodes
In the best case the depth will be about O(log N).In the worst case, if the data are already ordered, the depth will be about O(N).
Effects of Data Order…
So, if the input data are randomly ordered, what is the average depth of the nodes?The analysis is beyond the scope of this course, but it can be shown that the average depth is O(log N), which is a very nice result.
SummaryIn this lecture we showed that, for an average binary search tree, the average depth of the nodes is O(log N). This is quite amazing, indicating that the bad situations, which are O(N), don’t occur very often.However, for those who are still concerned about the very bad situations, we can try to “balance” the trees. This is the subject for the next lecture.