Binary Search Tree
Tree Tree
A nonlinear data structure consisting of nodes, each of which contains data and pointers to other nodes.
Each node has only one predecessor (parent), except the root node, which has none.
ΩΩΩ ΩΩ Ω
Ω Ω Ω Ω ΩΩ
Tree Data Structure
Ω
Terminology Node
Contains data and pointers to other nodes (called child nodes)
Parent Node Each node has at
most one node. Root node has no
parent Leaf
Node with no children
ΩΩ ΩΩ ΩΩ Ω
Ω Ω Ω Ω ΩΩ
Ω Ω
Root Node
Leaf Node Leaf Node
Leaf Node
Leaf Node
Terminology Height of Tree
Longest path to a leaf
Subtree A node and all its
children Edge (or link)
A path from a node to its child
Null pointer Points to no node
(in C++, 0)
ΩΩ ΩΩ ΩΩ Ω
Ω Ω Ω Ω ΩΩ
Ω Ω
Root Node
(Ω)
Binary Tree
Binary Tree is a nonlinear linked
structure in which each node may point to two other nodes, and every node but the root node has a single predecessor.
Root Node
Left Subtree Right Subtree
Binary Search Tree
Binary Search Tree Binary tree in which a
data item is inserted in such a way that all items less than the
item in a node are in the left subtree
All items greater than the item in a node are in the right subtree
30
25 50
15 60
55205
Root Node
Left Subtree Right Subtree
Traversals
Any process for visiting the nodes in some order is called a traversal.E.g., printing, searching.
Traversals
Preorder traversal: Visit the root, then visit its left and right subtrees
(children) Postorder traversal:
Visit the left and right subtrees (children), then visit the root
Inorder traversal: Visit the left subtree, then the root, then the right
subtree.
Preorder Traversal1
2 3
Postorder Traversal
1 2
3
Inorder Traversal
1
2
3
Representing Node
struct TreeNode { elemType value; // value in node TreeNode *left; // pointer to left child TreeNode *right; // pointer to right child}; TreeNode *root; // pointer to root node
Note the recursive form of the declaration.
30
BST Operations (Public)typedef int elemType;
class BinTree {public: BinTree(); void insertNode(elemType item); bool search(elemType item); void remove(elemType item); void displayInOrder(); void displayPreOrder(); void displayPostOrder();private: . . . Private declarations};
Private Methodsclass BinTree {public: . . . Public methodsprivate: struct TreeNode { elemType value; // value in node TreeNode *left; // pointer to left child node TreeNode *right; // pointer to right child node }; TreeNode *root; // pointer to the root node
void insert(TreeNode *&nodePtr, TreeNode *&newNode); void removeNode(elemType item , TreeNode *&nodePtr); void makeRemoval(TreeNode *&nodePtr); void displayInOrder(TreeNode *nodePtr); void displayPreOrder(TreeNode *nodePtr); void displayPostOrder(TreeNode *nodePtr);};
BST Constructor
#define NULL 0
BinTree::BinTree() { root = NULL; // NULL pointer}
BST InsertNode Operation
To DisplayInOrder
BST InsertNode Operationvoid BinTree::insertNode(elemType item) { TreeNode *newNode; // pointer to new node
// Create new node and store item newNode = new TreeNode; newNode->value = item; newNode->left = newNode->right = NULL;
// Insert the node insert(root, newNode); }
BST Insert Method (Private)void BinTree::insert(TreeNode *&nodePtr, TreeNode *&newNode) { if (nodePtr == NULL) // Insert the node nodePtr = newNode; else if (newNode->value < nodePtr->value) // Attach on left subtree insert(nodePtr->left, newNode); else // Attach on right subtree insert(nodePtr->right, newNode); }
TreeNode *&NodePtr — nodePtr is reference to actual argument
Order of Insertion Affects Tree Height
37, 24, 32, 42, 40, 42, 7, 120, 2
120, 42, 7, 42, 32, 2, 37, 40, 24
Which Structure Allows More Efficient Search?
37
24 42
7 4232 40
1202
2
7
24
32
37
40
42
42
120
42Key Value:
BST DisplayInOrder Operation
void BinTree::displayInOrder() { displayInOrder(root);}
BST DisplayInOrder Method (Private)
void BinTree::displayInOrder( TreeNode *nodePtr) { if (nodePtr) { displayInOrder(nodePtr->left); cout << nodePtr->value << endl; displayInOrder(nodePtr->right); }}
To BST diagram
BST Remove Operation
When removing a node from a tree, there are 4 cases to consider1. The node is a leaf2. The node has no right child3. The node has no left child4. The node has both children
BST Remove Operation (Node is a leaf)
37
24 42
7 55
root
Ω Ω
Ω ΩΩ Ω
This node to be deleted
37
4224
55Ω
Ω
Ω
Ω
7
Ω Ω
Before After
BST Remove Operation (Node has no right child)
37
24 42
7 55
root
Ω Ω
Ω ΩΩ Ω
This node to be deleted
37
24 42
7 55Ω Ω
Ω ΩΩ Ω
Before
After
BST Remove Operation (Node has no left child)
37
24 42
7 55
root
Ω Ω
Ω ΩΩ Ω
This node to be deleted
37
4224
7 55Ω
Ω ΩΩ Ω
Ω
After
Before
BST Remove Operation (Node has both children)
This node to be deleted
37
24 42
7 55
root
Ω
Ω ΩΩ Ω
40
ΩΩ
37
24 42
7 55Ω
Ω ΩΩ Ω
40
ΩΩ
Before 37
24
55
7 Ω
Ω Ω
40
Ω Ω
After
BST remove Operation
void BinTree::remove(elemType item) { removeNode(item, root);}
BST removeNode Method (Private)
void BinTree::removeNode(elemType item , TreeNode *&nodePtr) { if (item == nodePtr->value) makeRemoval(nodePtr); else if (item < nodePtr->value) removeNode(item, nodePtr->left); else // item > nodePtr->value removeNode(item, nodePtr->right); }
BST makeRemoval Method (Private)void BinTree::makeRemoval(TreeNode *&nodePtr) { TreeNode *tempPtr;
if (nodePtr == NULL) cout << "Cannot remove empty node.\n"; else if (nodePtr->right == NULL) { // no right child tempPtr = nodePtr; nodePtr = nodePtr->left; // reattach left child delete tempPtr; } else if (nodePtr->left == NULL) { // no left child tempPtr = nodePtr; nodePtr = nodePtr->right; // reattach right child delete tempPtr; } . . .
This is where *&nodePtr becomes important.
BST makeRemoval Method (cont.)
else { // node has right and left children // check the right subtree tempPtr = nodePtr->right;
// got to end of left subtree while (tempPtr->left) tempPtr = tempPtr->left;
// reattach left subtree tempPtr->left = nodePtr->left; tempPtr = nodePtr;
// reattach right subtree nodePtr = nodePtr->right; delete tempPtr; }}