Lec 6,7 BST

Download as pdf or txt
Download as pdf or txt
You are on page 1of 47

Benha University

Benha Faculty of Engineering Electrical Engineering Department

Data Structures and Algorithms


with C ++ (E1324)
LEC_6,7 Tree
Lecturer:
Dr. Eman Salem 1
Today’s Discussion…
 We will cover:
 Definition of a tree data structure
and its components.
 Definition of binary tree.
 Binary Search Tree Operations
 Searching for an item
 Inserting a new item
 Deleting an item
 Finding the minimum and maximum items
 Binary Search Tree Traversals:
A means of visiting all the objects in a tree data structure
We will look at
Breadth-first traversals
Depth-first traversals
Tree Data Structure
 It is a non-linear collection of data items, also linked together with pointers like a linked list.
 Each node may contain 2 or more pointers to other nodes.
root ptr
Empty tree NULL

5
Root node

L child -33 17
R child
NULL

53 91 -115
Leaf node
NULL NULL NULL NULL NULL NULL
Tree Terminology A

▪ Every tree has a "root" pointer.


The top node of a tree is called its "root" node. B C D
▪ Root: a node without a parent Ex: A is the root
▪ Internal node: a node with at least one child
E F G H
▪ Ex: A, B, C, F are internal nodes
▪ Leaf (External node): a node without children or
I J K
Nodes with degree zero . Ex: E, I, J, K, G, H, D are leaves
▪ Ancestors of a node: parent, grandparent, great-grandparent, etc.
▪ Ex: K’s ancestors are F, B, and A

4
▪ Siblings: nodes that have the same parent
Ex: E and F; I, J, and K; G and H; B, C and D A

▪ Descendant of a node: child, grandchild, great-grandchild, etc.


B C D
▪ Ex: B’s descendants are E, F, I, J and K

▪ Subtree: tree consisting of a node and its descendants


E F G H
(Right subtree, Left subtree)

▪ Edge: a pair of nodes (𝐶, 𝐻) such that 𝐶 is a parent of 𝐻 ((𝐶, 𝐻)) I J K

▪ Path: A sequence of nodes such that any two consecutives nodes form an edge (𝐴, 𝐵, 𝐹, 𝐽)

▪ A tree with no nodes is called an “empty tree”

▪ The degree of a node is defined as the number of its children : deg(A) = 3


depth of a node : number of ancestors
or number of edges in the path from the root to that node

Height of a node : number of levels – 1


Or number of edges in the path from the node to leaf node

For each node in a tree, there exists a unique path from the root node to that node.
The length of this path is the depth of the node, e.g.,
 E has depth 2
 L has depth 3

For convenience, we define the height of the empty tree to be –1


MAX Height of a tree: maximum depth of that tree.
Size of tree : number of nodes in tree
Length of tree : the longest path from root to leaf
Binary Tree
Binary Trees
A binary tree is a special form of tree. In a binary tree, every node has at most two children nodes:
A left child and a right child.

Each node contains a data element, and two pointers, each of which points to another node.
Alternative recursive definition: a binary tree is either
▪a tree consisting of a single node, or
▪a tree whose root has an ordered pair of children, each of which is a binary tree
Each node Implementation
struct TreeNode
{
InfoNode info ; // Data member
TreeNode* left ; // Pointer to left child
TreeNode* right ; // Pointer to right child
};

NULL Data 6000

. left . info . right


Binary Tree

▪ Complete Binary Tree: let ℎ be the height of the tree Perfect binary
trees are balanced
▪ for 𝑖 = 0 … ℎ − 1, there are 2𝑖 nodes on level 𝑖
while linked lists
▪ at level ℎ, nodes are filled from left to right are not
▪ The order is identical to that of a breadth-first traversal
Arr = [12 13 15 2 9 17 20 1] BFS

Parent index (i) = (i/2)-1


Child(i): left child idex = 2*i +1
: right child idex = 2*i +2

Ex: Ex
Left Child of 9 = 2*4+1 = 9 Parent of node 12 = (i/2)-1 =-1
right Child of 9 = 2*4+2= 10 -ve value means no parent
Node 9 don’t have left and right children
Ex
Parent of node 13 = (1/2)-1 =0
Ex:
Left Child of 15 = 2*2+1 = 5
right Child of 15 = 2*4+2= 6
# of edges in tree = # of nodes -1
Operations on Binary Trees
•Searching for an item
• Adding a new item at a certain position on the tree
• Deleting an item

•Binary Tree Traversals:


• Breadth-first traversals BFS root
(Level-order traversal) “a”

• Depth-first traversals DFS


1. Pre-order traversal
NULL NULL
2. In-order traversal
3. Post-order traversal

NULL NULL 14 NULL NULL


Binary Search Trees
Binary Search Trees
Why should you care?

Binary Search Trees are an extremely


efficient way to store/search for data!

You can search a BST with billions of


items in just microseconds!

They’re used in databases, search


engines, etc.

And because you’ll be asked about them


in job interviews and on exams.

So pay attention!
Binary Search Trees BST
5
Binary Search Trees are a type of binary tree with specific
properties that make them very efficient to search for a 3 7
value in the tree. 2 4 9
 Binary Search Tree Property:
Here’s an example BST…
 The value stored at a node is greater than the
value stored at its left child and less than the
value stored at its right child
 Thus, the value stored at the root of a subtree
is greater than any value in its left subtree and
less than any value in its right subtree!!

Binary search - finds a path through the tree, starting


at the "root", and each chosen path (left or right node)
eliminates half of the stored values.
Very useful for fast searching and sorting of data,
assuming the data is to be kept in some kind of order.
Operations on a Binary Search Tree

 Search in the binary search tree for a value


 Insert an item in the binary search tree
 Delete an item from the binary search tree
 Traverse the binary search tree
 Finding the Minimum in a Binary Search Tree
 Finding the Maximum in a Binary Search Tree
1- Searching for a Key
 Idea
15
 Starting at the root: trace down a path by
comparing k with the key of the current node(Keep 6 18

going until we hit the NULL pointer) 3 7 17 20


2 4 13
 If the keys are equal: we have found the key DONE!
9
(nothing to do...)
 If k < key[x] search in the left subtree of x
Search for key 13:
 If k > key[x] search in the right subtree of x
15 → 6 → 7 → 13
 If we hit a NULL pointer, not found.

current node value x


Big Oh of BST Search
Question:
In the average BST with N values,
50% 50% eliminated!
how many steps are required to
eliminated
find our value? !
Right! log(N) steps 50%
eliminated
Running Time: O (h),
50% !
h – the height of the tree
eliminated
!
Question:
In the worst case BST with
N values, how many steps are
required find our value?
Right! N steps

WOW!
Is this better than searching a linked list? Yes !! ---> O(logN)
Now that’s!
BST Search(find) Implementation
node* search_N(node* root, int x)
{
if(root == NULL)
{
cout<< "the key not exist";
return NULL;
}

if (root->data == x)
{cout<< "the key is :"<<x;
return root;}

else if(x < root->data)


root->left= search_N(root->left, x);
else if(x > root->data)
root->right= search_N(root->right, x);

}
2- Insertion
 Goal:
Insert value 13
 Insert value v into a binary search tree
12
 Idea:
 If the tree is empty 5 18
Allocate a new node and put V into it 2 9 15 19
Point the root pointer to our new node. DONE! 1 3 13 17

 Start at the root


- If current node value x < v move to the right child of x,
else move to the left child of x
- When x is NULL, we found the correct position
Example: TREE-INSERT
x=root
Insert 13: 12 12
x
5 18 5 18
2 9 15 19 2 9 15 19
1 3 17 1 3 17

12 12

x
5 18 5 18
2 9 15 19 2 9 15 19
1 3 17 1 3 13 17
x = NIL
y = 15
Does the order of inserting elements
into a tree matter?
 Yes, certain orders produce very unbalanced trees!!
 Unbalanced trees are not desirable because search time
increases!!
 There are advanced tree structures (e.g.,"red-black
trees, AVL tree") which guarantee balanced trees

To insert a new node in our BST, we must place the


new node so that the resulting tree is still a valid
BST!
Big Oh of BST Insertion
So, what’s the big-oh of BST Insertion?

Right! It’s also O(log n)

Why? Because we have to first use a binary search to find where to insert our
node and binary search is O(log n).

25
BST Insertion Implementation

node* insert_val(int x, node* root)


{
if(root == NULL)
{
root = new node;
root->data = x;
root->left = root->right = NULL;
}
else if(x < root->data)
root->left = insert_val(x, root->left);

else if(x > root->data)


root->right = insert_val(x, root->right);
}
First, find the item; then, delete it

Important: binary search tree


property must be preserved!!
Function
Delete Item We need to consider three different
cases:
• (1) Deleting a leaf
• (2) Deleting a node with only one child
• (3) Deleting a node with two children
Deletion

 Goal:
If the node was found,
 Delete a given node z from a binary search tree delete it from the tree,
 Idea: making sure to preserve
its ordering!
 Case 1: z has no children
 Delete z by making the parent of z point to NulL

15 15
5 16 5 16
3 12 20 3 12 20
10 13 z 18 23 10 18 23
6 delete
6
7 7
 Case 2: z has one child
 Delete z by making the parent of z point to z’s child, instead of to z

15 delete 15
z
5 16 5 20

3 12 20 3 12 18 23

10 13 18 23 10

6 6

7 7
29
 Case 3: z has two children
 By choosing the minimum node in z’s right subtree or
 By choosing the maximum node in z’s left subtree

6
15
delete z
15
5 16
6 16
3 12 20
3 12 20
10 13 18 23
10 13 18 23
6

y 7
7
BST Delete Implementation Begin from root

node* remove_n(int x, node* t) {


node* temp; else if(temp->right == NULL)
if(t == NULL) {temp = temp->left;
return NULL; delete t;
else if(x < t->data) // search data return temp;}
t->left = remove_n(x, t->left);
else if(x > t->data) // node with two children
t->right = remove_n(x, t->right); else{
else // found data temp = findMin(t->right);
{ // node with only one child or no child t->data = temp->data;
temp = t; t->right = remove_n(t->data, t->right);
if(temp->left == NULL) }
{ }
temp = temp->right; }
delete t;
return temp;
}
There are mainly three ways to
traverse a tree:

Tree Breadth First (Level Order BFS)


Traversals
Inorder Traversal

Postorder Traversal

Preorder Traversal
There are 2 common ways to traverse a tree.
Each technique differs in the order that each node is visited during the traversal:

• Breadth-first traversals BFS


(Level-order traversal)

• Depth-first traversals DFS


1. Pre-order traversal
2. In-order traversal
3. Post-order traversal

A means of visiting all the nodes in a tree data structure


Any time we traverse through a tree, we always start with the root node.
Breadth-First Traversal BFS
Level-order Traversal: Level-by-level
:
 The breadth-first traversal visits all nodes
at depth k before proceeding onto depth k + 1
 Easy to implement using a queue
 Run time is O(n)
To determine the order of nodes visited in a level-order traversal…
Level-order:
Start at the top node and draw a horizontal line left-to-right through ABHCDGI EHJK
all nodes on that row.
Repeat for all remaining rows.
The order you draw the lines is the order of the level-order traversal!
Another approach is to visit always go as deep as possible before
visiting other siblings: depth-first traversals
Array storage

We can store this in an array after a quick traversal: To insert another node while maintaining the complete-
binary-tree structure, we must insert into the next array
location
BST BFS Implementation

void BFS_level_order()
The implementation was already discussed: {
• Create a queue and push the root node if (root == NULL) return;
onto the queue queue < node*> q;
• While the queue is not empty: q.push(root);
Push all of its children of the front node
onto the queue
while(!q.empty())
Pop the front node
{
node *current= q.front();
if (current->left!= NULL)
q.push(current->left);
if (current->right!= NULL)
q.push(current->right);
cout<<current->data<<" ";
q.pop();
} cout<<endl;}
Depth-first Traversal
Inorder Traversal: Visit second
Visit the nodes in the left subtree,
then visit the root of the tree, tree
then visit the nodes in the right subtree .
(Warning:
"visit" means that the algorithm ‘J’
does something with the values

in the node, e.g., print the value) ‘E’ ‘T’

‘A’ ‘H’ ‘M’ ‘Y’


•An inorder traversal of a BST visits
the keys in ascending order
Hint: use binary search trees for sorting !! Visit right subtree last
Visit left subtree first

AEHJMTY
Postorder Traversal
Visit last
Visit the nodes in the left subtree first,
then visit the nodes in the right subtree, tree
then visit the root of the tree

‘J’

‘E’ ‘T’

‘A’ ‘H’ ‘M’ ‘Y’

Visit left subtree first Visit right subtree second

: AH E MYTJ
Preorder Traversal:
Visit first
Visit the root of the tree first,
then visit the nodes in the left subtree, tree
then visit the nodes in the right subtree

‘J’

‘E’ ‘T’

‘A’ ‘H’ ‘M’ ‘Y’

Visit left subtree second Visit right subtree last


39

JEAHTMY
Tree
Traversals
5

3 7
2 5 9

Inorder: 2 3 5 5 7 9
Preorder: 5 3 2 5 7 9
Postorder: 2 5 3 9 7 5
BST DFS Implementation

void preorder(node* t) { void postorder(node* t)


void inorder(node* t) { if(t == NULL) {
if(t == NULL) return; if(t == NULL)
return; cout << t->data << " return;
inorder(t->left); ";
cout << t->data << " preorder(t->left); postorder(t->left);
"; preorder(t->right); postorder(t->right);
inorder(t->right); } cout << t->data << "
} ";
}

Begin from root


Finding the Minimum and Maximium in a BST
 Goal: find the maximum value in a BST
 Goal: find the minimum value in a BST
 Following right child pointers from the root,
 Following left child pointers from the root,
until a NIL is encountered
until a NIL is encountered

 Running time: O(h), h – height of tree


Running time: O(h), h – height of tree

15 15

6 18 6 18
3 7 17 20 3 7 17 20
2 4 13 2 4 13
9 9
Minimum = 2 Maximum = 20
Finding Min & Max of a BST
And here are recursive versions for you…

node* findMin(node* t) node* findMax(node* t)


{ {
if(t == NULL) if(t == NULL)
return NULL; return NULL;
else if(t->left == NULL) else if(t->right == NULL)
return t; return t;
else else
return findMin(t->left); return findMax(t->right) }
}

Begin from root

Hopefully you’re getting the idea that most tree functions can be done
recursively…
Binary Search Trees - Summary
 Operations on binary search trees:
 SEARCH O(h)
 INSERT O(h)
Running time of basic operations on BST (logn)
 DELETE O(h)

The expected height of the tree is log(n)  MINIMUM O(h)


 MAXIMUM O(h)

In the worst case: (n)


The tree is a linear chain of n nodes These operations are fast if the height
of the tree is small – otherwise their
performance is similar to that of a linked list
Any question?

If you try to solve problems yourself, then you


will learn many things automatically.

Spend few minutes and then enjoy the study.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy