0% found this document useful (0 votes)
47 views

Lecture 12 Binary Search Trees Implementation

The document discusses the implementation of a binary search tree (BST). It begins by defining the properties of a BST, where all elements in the left subtree are less than the root node and all elements in the right subtree are greater. It then provides examples and discusses various BST operations like creating and initializing a BST, finding a node, inserting a node, and deleting a node. For inserting, it explains that new nodes can be added as leaf nodes and discusses the algorithm. For deletion, it notes there are three cases to handle depending on if the node is a leaf, has one child, or two children.

Uploaded by

Prhna Wala Bacha
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views

Lecture 12 Binary Search Trees Implementation

The document discusses the implementation of a binary search tree (BST). It begins by defining the properties of a BST, where all elements in the left subtree are less than the root node and all elements in the right subtree are greater. It then provides examples and discusses various BST operations like creating and initializing a BST, finding a node, inserting a node, and deleting a node. For inserting, it explains that new nodes can be added as leaf nodes and discusses the algorithm. For deletion, it notes there are three cases to handle depending on if the node is a leaf, has one child, or two children.

Uploaded by

Prhna Wala Bacha
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 53

CS-2001

Data Structures
Fall 2023
Binary Search Tree Implementation

Mr. Muhammad Usman Joyia


National University of Computer and
Emerging Sciences,
Faisalabad, Pakistan.
Binary Search Tree (BST)
• With a binary tree, we can dictate an order on the two children

• Binary Search Tree (BST) defines the following order:

– All elements in the left sub-tree to be less than the element stored in
the root node, and

– All elements in the right sub-tree to be greater than the element in the
root object

subtrees will
themselves be
binary search trees

2
Binary Search Tree (BST) – Example (1)

3
Binary Search Tree (BST) – Example (2)

10
2 45 10

5 30
5 45
30

2 25 45
10 2 25 30

BST
25 Not BST

BST

4
BST Operations
• Many operations one can perform on a binary search tree

– Creating a binary search tree

– Finding a node in a binary search tree

– Inserting a node into a binary search tree

– Deleting a node in a binary search tree

– Traversing a binary search tree

• In the following, we will examine the algorithms and examples for


all of the above operations
5
Creating BST
• A simple class that implements a binary tree to store integer values
– A class called IntBinaryTree

• Node of binary search tree

struct TreeNode
{
int value;
TreeNode *left;
TreeNode *right;
};

6
Creating BST – Class Definition
class IntBinaryTree {
private:
TreeNode *root; // Pointer to the root of BST

void destroySubTree(TreeNode *); //Recursively delete all tree nodes


void deleteNode(int, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *);
void displayPreOrder(TreeNode *);
void displayPostOrder(TreeNode *);

public:
IntBinaryTree() { root = NULL; }
~IntBinaryTree() { destroySubTree(root); }
void insertNode(int);
bool find(int);
void remove(int);
void showNodesInOrder() { displayInOrder(root); }
void showNodesPreOrder() { displayPreOrder(root); }
void showNodesPostOrder() { displayPostOrder(root); }
};
7
Finding a Node in BST
• Recall that a BST has the following key property (invariant):
– Smaller values in left sub-tree
– Larger values in right sub-tree

• For example: find (81)


– Returns true if found

8
Finding a Node in BST
• Recall that a BST has the following key property (invariant):
– Smaller values in left sub-tree
– Larger values in right sub-tree

• For example: find (36)


– Returns false if not found

9
Finding a Node in BST
• Example: find(2)

root
10
10 > 2, left
5 30 5 > 2, left
2 = 2, found
2 25 45

10
Finding a Node in BST
• Example: find(25)

root
5
5 < 25, right
2 45
45 > 25, left
30 > 25, left
30
10 < 25, right
10 25 = 25, found

25
11
Finding a Node in BST – Implementation
bool IntBinaryTree::Find(int num){
// The function starts from the root
TreeNode *nodePtr = root;

while (nodePtr) {
if (nodePtr->value == num)
return true; // value is found
else if (num < nodePtr->value)
nodePtr = nodePtr->left;
else
10 10 < 25, right
nodePtr = nodePtr->right;
}
return false; // value not found 5 30 30 > 25, left

}
25 = 25, found
2 25 45
12
Inserting a Node in BST
• An insertion will be performed as a leaf node
– Any empty node is a possible location for an insertion

• Values which may be inserted at any empty node depend on the


surrounding nodes

13
Inserting a Node in BST
• Which values can be held by empty node?

This node may hold


48, 49, or 50

14
Inserting a Node in BST
• Which values can be held by empty node?

This node may hold


35, 36, 37 or 38

15
Inserting a Node in BST – Algorithm
• Like find, algorithm will step through the tree
– If algorithm find the object already in the tree, it will return
 The object is already in the binary search tree (no duplicates)
– Otherwise, algorithm will arrive at an empty node
– The object will be inserted into that location

16
Inserting a Node in BST – Example
• insertNode(20)

10
10 < 20, right
5 30
30 > 20, left
25 > 20, left
2 25 45
Insert 20 on left

20

17
Inserting a Node in BST – Implementation
void IntBinaryTree::insertNode(int num) {

TreeNode* newNode = new TreeNode; // Create a new node


newNode->value = num;
newNode->left = newNode->right = NULL;

if (!root) root = newNode; // If tree is empty.


else { // Tree is not empty
TreeNode* nodePtr = root; // create a pointer to traverse the tree
while ( true ) {
if (num < nodePtr->value) { // Left subtree
if (nodePtr->left!=NULL) { nodePtr = nodePtr->left; }
else { nodePtr->left = newNode; return; }
}
else if (num > nodePtr->value) { // Right subtree
if (nodePtr->right !=NULL) {nodePtr = nodePtr->right;}
else { nodePtr->right = newNode; return; }
}
else { cout << "Duplicate value found in tree.\n"; break; }
}
}
} 18
Inserting a Node in BST – Observation (1)
• Insertion may unbalance the tree
• It is possible to have a degenerate BST
– The example is equivalent to a linked list

19
Inserting a Node in BST – Observation (2)
• All these binary search trees store the same data
– Resultant tree depends on the order in which the values are inserted

20
Using BST (1)
// This program builds a binary tree with 5 nodes.

#include <iostream.h>
#include "IntBinaryTree.h“
Output:
void main(void)
Inserting nodes.
{ 3 is found in the tree.
IntBinaryTree tree;

cout << "Inserting nodes.\n";


tree.insertNode(5);
tree.insertNode(8);
tree.insertNode(3);
tree.insertNode(12);
tree.insertNode(9);
if (tree.Find(3))
cout << "3 is found in the tree.\n";
else
cout << "3 was not found in the tree.\n";
}

21
Using BST (2)
• Structure of binary tree built by the program

22
Deleting a Node
• A node being erased is not always going to be a leaf node
• There are three possible scenarios:
– The node is a leaf node,
– It has exactly one child, or
– It has two children (it is a full node)

23
Deleting a Node – Leaf Node
• Deleting a leaf node is easy
– Find its parent
– Set the child pointer that links it with parent to NULL
– Free the node’s memory

• Consider deleting node containing 25

10 10
10 < 25, right
5 30 30 > 25, left 5 30
25 = 25, delete
2 25 45 2 45

24
Deleting a Node – Leaf Node
• Consider deleting node containing 75

25
Deleting a Node – Leaf Node
• Consider deleting node containing 75
– The node is deleted and left child of 81 is set to NULL

26
Deleting a Node – Leaf Node
• Consider deleting node containing 40

27
Deleting a Node – Leaf Node
• Consider deleting node containing 40
– Node is deleted and right child of 39 is set to NULL

28
Deleting a Node – Node With Child
• If a node has only one child (left or right)
– Simply promote the subtree associated with the child

• Consider deleting 18 which has one right child


– Node 18 is deleted and right tree of node 5 is updated to point to 21

29
Deleting a Node – Node With Child
• Consider deleting 8 which has one left child

30
Deleting a Node – Node With Child
• Consider deleting 8 which has one left child
– Node 8 is deleted and the left tree of 11 is updated to point to 3

31
Deleting a Node – Node With Child
• Consider deleting the node containing 99

32
Deleting a Node – Node With Child
• Consider deleting the node containing 99
– The right tree of 70 is set to point to node 92
– Again, the order of the tree is maintained

33
Deleting a Node – Node With Two Children
• The problem is not as easily solved if the node has two children

34
Deleting a Node – Node With Two Children
• Suppose node p with two children has to be deleted
– Find a position in the right subtree of p to attach its left subtree
 Left most node in the right subtree of node p (successor of p )
– Attach the right subtree of node p to its parent
• Consider deleting 10
10
30
30
10
25 45
25 45
5 30
5
5 Attach left
Attach right
subtree of
2 25 45 10 to that subtree of
node, i.e., 25
2 10 to its
Find left most node of 2 parent
right subtree of 10 35
Pointers Review
• Pointer to Pointer versus reference to Pointer?

int g_One=1; int g_One=1;

void func(int* pInt); void func(int*& rpInt);

int main() int main()


{ {
int nvar=2; int nvar=2;
int* pvar=&nvar; int* pvar=&nvar;
func(pvar); func(pvar);
std::cout<<*pvar<<std::endl; std::cout<<*pvar<<std::endl;
return 0; return 0;
} }

void func(int* pInt) void func(int*& rpInt)


{ {
pInt=&g_One; rpInt=&g_One;
} }

36
Deleting a Node – Implementation
class IntBinaryTree {
private:
TreeNode *root; // Pointer to the root of BST

void destroySubTree(TreeNode *); //Recursively delete all tree nodes


void deleteNode(int, TreeNode *&);
void makeDeletion(TreeNode *&);
void displayInOrder(TreeNode *);
void displayPreOrder(TreeNode *); The argument passed to the
void displayPostOrder(TreeNode *); remove function is the value of
the node to be deleted.
public:
IntBinaryTree() { root = NULL; }
~IntBinaryTree() { destroySubTree(root); }
void insertNode(int);
bool find(int);
void remove(int num); { deleteNode( num, root)}
void showNodesInOrder() { displayInOrder(root); }
void showNodesPreOrder() { displayPreOrder(root); }
void showNodesPostOrder() { displayPostOrder(root); }
};
37
Deleting a Node – Implementation
void IntBinaryTree::deleteNode(int num, TreeNode *&nodePtr)
{
if (nodePtr == NULL) // node does not exist in the tree
cout << num <<“ not found.\n";
else if (num < nodePtr->value)
deleteNode(num, nodePtr->left); // find in left subtree

else if (num > nodePtr->value)


deleteNode(num, nodePtr->right); // find in right subtree

else // num == nodePtr->value i.e. node is found


makeDeletion(nodePtr); // actually deletes node from BST
}
Note:
• The declaration of the nodePtr parameter: TreeNode *&nodePtr;
• nodePtr is a reference to a pointer to a TreeNode structure
– Any action performed on nodePtr is actually performed on the argument
passed into nodePtr 38
Deleting a Node – Implementation
void IntBinaryTree::makeDeletion(TreeNode *&nodePtr) {
TreeNode *tempNodePtr; // Temperary pointer
if (nodePtr->right == NULL) { // case for leaf and one (left) child
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL) { // case for one (right) child
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right child
delete tempNodePtr;
}
else { // case for two children.
tempNodePtr = nodePtr->right; // Move one node to the right
while (tempNodePtr->left) { // Go to the extreme left node
tempNodePtr = tempNodePtr->left;
}
tempNodePtr->left = nodePtr->left; // Reattach the left subtree
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Reattach the right subtree
delete tempNodePtr;
} 39
}
Deleting a Node – Node With Two Children
• Problem: Height of the BST increases

• A better Solution to delete node p with two children


– Replace node p with the minimum object in the right subtree
– Delete that object from the right subtree

40
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 42

41
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 42
– Find minimum object in the right subtree, i.e., 47

42
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 42
– Find minimum object in the right subtree, i.e., 47
– Replace 42 with 47

43
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 42
– Find minimum object in the right subtree, i.e., 47
– Replace 42 with 47
– Delete the leaf node 47

44
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 47

45
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 47
– Replace 47 with 51

46
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 47
– Replace 47 with 51
– Node 51 is not a leaf node

47
Deleting a Node Two Children – Better Solution
• Consider the problem of deleting a full node, e.g., 47
– Replace 47 with 51
– Node 51 is not a leaf node
 Assign the left subtree of 70 to point to 59

48
Using BST
// This program builds a binary tree with 5 nodes.
// The DeleteNode function is used to remove two of them.
#include <iostream.h>
#include "IntBinaryTree.h“ Program Output:
void main(void) {
Inserting nodes.
IntBinaryTree tree; Here are the values in
the tree:
cout << "Inserting nodes.\n"; 3
tree.insertNode(5);
tree.insertNode(8); 5
tree.insertNode(3); 8
tree.insertNode(12); 9
tree.insertNode(9);
12
cout << "Here are the values in the tree:\n";
tree.showNodesInOrder();
cout << "Deleting 8...\n";
tree.remove(8);
cout << "Deleting 12...\n";
tree.remove(12);

cout << "Now, here are the nodes:\n";


tree.showNodesInOrder();
}
49
Using BST
// This program builds a binary tree with 5 nodes.
// The DeleteNode function is used to remove two of them.
#include <iostream.h>
#include "IntBinaryTree.h“ Program Output:
Inserting nodes.
void main(void) {
IntBinaryTree tree; Here are the values in
the tree:
cout << "Inserting nodes.\n"; 3
tree.insertNode(5);
tree.insertNode(8);
5
tree.insertNode(3); 8
tree.insertNode(12); 9
tree.insertNode(9); 12
cout << "Here are the values in the tree:\n"; Deleting 8...
tree.showNodesInOrder(); Deleting 12...
cout << "Deleting 8...\n"; Now, here are the
tree.remove(8); nodes:
cout << "Deleting 12...\n";
tree.remove(12); 3
5
cout << "Now, here are the nodes:\n"; 9
tree.showNodesInOrder();
}
50
Traversing a Binary Search Tree
class IntBinaryTree {
private:
TreeNode *root; // Pointer to the root of BST

void destroySubTree(TreeNode *); //Recursively delete all tree nodes


void deleteNode(int, TreeNode *&);
void makeDeletion(TreeNode *&);
Recursive implementation as
void displayInOrder(TreeNode *);
void displayPreOrder(TreeNode *); discussed in the slides of Tree
void displayPostOrder(TreeNode *); Traversal chapter.

public:
IntBinaryTree() { root = NULL; }
~IntBinaryTree() { destroySubTree(root); }
void insertNode(int);
bool find(int);
void remove(int);
void showNodesInOrder() { displayInOrder(root); }
void showNodesPreOrder() { displayPreOrder(root); }
void showNodesPostOrder() { displayPostOrder(root); }
};
51
Program output:
Using BST Inserting nodes.
Inorder traversal:
// This program builds a binary tree with 5 nodes. 3
// The nodes are displayed with inorder, preorder, and 5 algorithms.
postorder
#include <iostream.h> 8
#include "IntBinaryTree.h“
9
void main(void) 12
{
IntBinaryTree tree;
Preorder traversal:
cout << "Inserting nodes.\n"; 5
tree.insertNode(5); 3
tree.insertNode(8); 8
tree.insertNode(3);
tree.insertNode(12); 12
tree.insertNode(9); 9

cout << "Inorder traversal:\n";


tree.showNodesInOrder();
Postorder traversal:
cout << "\nPreorder traversal:\n"; 3
tree.showNodesPreOrder();
9
cout << "\nPostorder traversal:\n";
tree.showNodesPostOrder(); 12
} 8
5
52
Any Question So Far?

53

You might also like