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

CENG 205

Data structures
Lecture 11:
Trees
Content
• Terminology
• The Binary Tree
• The Binary Search Tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Terminology

• Trees are used to represent relationships


• Trees are hierarchical in nature
• “Parent-child” relationship exists between nodes in tree.
• Generalized to ancestor and descendant
• Lines between the nodes are called edges
• A subtree in a tree is any node in the tree together with all
of its descendants

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Terminology
• Only access point is the root
• All nodes, except the root, have one parent
• like the inheritance hierarchy in Java
• Traditionally trees are drawn upside down

root

leaves
Terminology

• (a) a tree;
(b) a subtree of the tree in part a

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Terminology

• FIGURE 15-2 (a) An organization chart; (b) a family tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Properties of Trees and Nodes
root
• siblings: two nodes that have the same
parent edge
• edge: the link from one node to another
• path length: the number of edges that
must be traversed to get from one node
to another
siblings

path length from root to this


node is 3
General Tree
• A general tree is a data structure in that each node can have infinite
number of children
• A general tree cannot be empty.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Binary Tree

• A Binary tree is a data structure in that each node has at most two
nodes left and right.
• A Binary tree can be empty.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
n -ary tree
• A generalization of a binary tree whose nodes each can have no
more than n children.

n
Example: Algebraic Expressions.

• FIGURE 15-3 Binary trees that represent


algebraic expressions

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Level of a Node
• Definition of the level of a node n :
• If n is the root of T, it is at level 1.
• If n is not the root of T, its level is 1 greater than the level of its parent.

Level = 1

Level = 2

Level = 3
Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Height of Trees
• The height of a node is the number of edges on the longest downward path
between that node and a leaf.

Height of tree = 2
The Height of Trees

Height 2 Height 4 Height 6 Height 6

• Binary trees with the same nodes but different heights


Depth of a Tree

• The path length from the root of the tree to this node.

The depth of a node is its distance from the


root
a a is at depth zero
e is at depth 2
The depth of a binary tree is the depth of its
b c
deepest node
This tree has depth 4
d e f

g h i j k

l
Full, Complete, and Balanced Binary Trees

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Full Binary Trees

• Definition of a full binary tree


• If T is empty, T is a full binary tree of height 0.
• If T is not empty and has height h > 0, T is a full binary tree if its root’s
subtrees are both full binary trees of height h – 1.
• Every node other than the
leaves has two children.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Facts about Full Binary Trees

• You cannot add nodes to a full binary tree without


increasing its height.
• The number of nodes that a full binary tree of height h
can have is 2 (h+1) – 1.
• The height of a full binary tree with n nodes is
log 2 (n+1)-1
• The height of a complete binary tree with n nodes is
floor(log 2 n)

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Complete Binary Trees

Every level, except possibly the last, is completely


filled, and all nodes are as far left as possible

• FIGURE 15-7 A complete binary tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Full,
Complete or A not binary
Other?
B C D

I H G F E

J K L M N O

T S R Q P
Full,
Complete or A
other?
B D

I H G F

K L M N O

T S R P
Full, A
Complete or
other?
B D

I H G F

K L O
M N

T S R P
Full, A
Complete or
other?
B D

I H G F

K L O
M N

T S R P
Full, A
Complete or
other?
B D

I H G F

K L O R P
M N

T S
Full, A
Complete or
Other?
B D

I H G F

K L M N O P Q R

T S
Full, A
Complete or
other?
B D

I H G F

K L M N O P Q R

T S
Full, A
Complete or
Other?
B D

I H G F

K L M N O P Q R
• A balanced binary tree has the minimum possible height for the leaves

a
b
c e
d f
g h
i j
An unbalanced binary
tree
Number of Nodes in a Binary Tree


depth: h level: h+1

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Traversals of a Binary Tree

• General form of recursive traversal algorithm


1.Preorder Traversal
Each node is processed before any node in either of
its subtrees
2.Inorder Traversal
Each node is processed after all nodes in its left
subtree and before any node in its right subtree
3.Postorder Traversal
Each node is processed after all nodes in both of its
subtrees

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Preorder Traversal
1. Visit the root
2. Visit the left subtree
1
A
3. Visit the right subtree

B
2 11
D

3I H
8 G
12 F
13

K
4 5
L O
14
M
9 N
10

T
6 S7 R
15 P
16
Algorithm TraversePreorder(n)
Process node n
if n is an internal node then
TraversePreorder( n -> leftChild)
TraversePreorder( n -> rightChild)
Inorder Traversal
1. Visit Left subtree
2. Visit the root 10
1A
3. Visit Right subtree

6B
1 12
D

2I
1 8
H G
11 16
F

K
1 4
L 14
O
M
7 N9

T
3 5
S R
13 P
15
Algorithm TraverseInorder(n)
if n is an internal node then
TraverseInorder( n -> leftChild)
Process node n
if n is an internal node then
TraverseInorder( n -> rightChild)
Postorder Traversals
1. Visit Left subtree
A
16
2. Visit Right subtree
3. Visit the root

B
9 D
15

5I H
8 G
10 F
14

K
1 L
4
2 O
13
M
6 N
7

T2 S
3 R
11 P
12
Algorithm TraversePostorder(n)
if n is an internal node then
TraversePostorder( n -> leftChild)
TraversePostorder( n -> rightChild)
Process node n
Traversals of a Binary Tree

• FIGURE 15-11 Three traversals of a binary tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Binary Tree Operations

• Test whether a binary tree is empty.


• Get the height of a binary tree.
• Get the number of nodes in a binary tree.
• Get the data in a binary tree’s root.
• Set the data in a binary tree’s root.
• Add a new node containing a given data item to a binary tree.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Binary Tree Operations

• Remove the node containing a given data item from a binary tree.
• Remove all nodes from a binary tree.
• Retrieve a specific entry in a binary tree.
• Test whether a binary tree contains a specific entry.
• Traverse the nodes in a binary tree in preorder, inorder, or postorder.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Represention of Binary Tree ADT
A binary tree can be represented using
- Linked List
- Array

Note : Array is suitable only for full and complete binary trees
struct node
{
int key_value;
struct node *left;
struct node *right;
};

struct node *root = 0;


void inorder(node *p) void preorder(node *p) void postorder(node *p)
{ { {
if (p != NULL) if (p != NULL) if (p != NULL)
{ { {
inorder(p->left); printf(p->key_value); postorder(p->left);
printf(p->key_value); preorder(p->left); postorder(p->right);
inorder(p->right); preorder(p->right); printf(p->key_value);
} } }
} } }
void destroy_tree(struct node *leaf)
{
if( leaf != 0 )
{
destroy_tree(leaf->left);
destroy_tree(leaf->right);
free( leaf );
}
}
The Binary Search Tree

• Binary tree is ill suited for searching a specific item


• Binary search tree solves the problem
• Properties of each node, n
• n’s value is greater than all values in the left subtree TL
• n’s value is less than all values in the right subtree TR
• Both TR and TL are binary search trees.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
The Binary Search Tree

• FIGURE 15-13 A binary search tree of names

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
The Binary Search Tree

• FIGURE 15-14 Binary search trees


• with the same data as in Figure 15-13

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
The Binary Search Tree

• FIGURE 15-14 Binary search trees


• with the same data as in Figure 15-13

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
The Binary Search Tree

• Binary search trees with the same data as in Figure 15-13

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Binary Search Tree Operations

• Test whether a binary search tree is empty.


• Get height of a binary search tree.
• Get number of nodes in a binary search tree.
• Get data in binary search tree’s root.
• Insert new item into the binary search tree.
• Remove given item from the binary search tree.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Binary Search Tree Operations

• Remove all entries from a binary search tree.


• Retrieve given item from a binary search tree.
• Test whether a binary search tree contains a specific entry.
• Traverse items in a binary search tree in
• Preorder
• Inorder
• Postorder.

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Searching a Binary Search Tree

• Search algorithm for binary search tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
struct node *search(int key, struct node *leaf)
{
if( leaf != 0 )
{
if(key==leaf->key_value)
{
return leaf;
}
else if(key<leaf->key_value)
{
return search(key, leaf->left);
}
else
{
return search(key, leaf->right);
}
}
else return 0;
}
Creating a Binary Search Tree

• Empty subtree where the search algorithm terminates when


looking for Frank

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
void insert(int key, struct node **leaf)
{
if( *leaf == 0 )
{
*leaf = (struct node*) malloc( sizeof( struct node ) );
(*leaf)->key_value = key;
/* initialize the children to null */
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(key < (*leaf)->key_value)
{
insert(key, &(*leaf)->left );
}
else if(key > (*leaf)->key_value)
{
insert(key, &(*leaf)->right );
}
}
Deleting An Item from a BST
• To delete an item from a BST, we have to locate that item in that BST.

• The deleted node can be:


– Case 1 – A leaf node.
– Case 2 – A node with only one child
(with left child or with right child).
– Case 3 – A node with two children.
Deletion – Case 1: A Leaf Node
To remove the leaf containing the item, we have to set the pointer in its parent to NULL.

50 50

40 60 40 60

30 45 70
30 45

42
42

Delete 70 (A leaf node)


Deletion – Case 2: A Node with only a left child

50
50

➔ 40 60
40 60

30 42 70
30 45 70

42

Delete 45 (A node with only a left child)


Deletion – Case 2: A Node with only a right
child

50
50

➔ 40 70
40 60

30 45
30 45 70

42
42

Delete 60 (A node with only a right child)


Deletion – Case 3: A Node with two children
• Locate the inorder successor of the node.

• Copy the item in this node into the node which contains the item which will be deleted.

• Delete the node of the inorder successor.

50 50

➔ 42 60
40 60

70 30 45 70
30 45

42

Delete 40 (A node with two children)


Deletion – Case 3: A Node with two children
Deletion – Case 3: A Node with two children

Delete 2
Deletion from a BST

void delete(int key, struct node **leaf)


{
if( *leaf == 0 )
return;
else if( key == (*leaf)->key_value )
deleteNode(&(*leaf));
else if( key < (*leaf)->key_value )
delete(key, &(*leaf)->left);
else if( key > (*leaf)->key_value )
delete(key, &(*leaf)->right);
}
Deletion from a BST
void deleteNode(struct node **leaf)
{
struct node *deleted;

// (1) Test for a leaf


if ( ((*leaf)->left == NULL) && ((*leaf)->right == NULL) )
{
free(*leaf);
*leaf = NULL;
}

// (2) Test for no left child


else if ((*leaf)->left == NULL){
deleted = *leaf;
*leaf = (*leaf)->right;
deleted->right = NULL;
free(deleted);
}
Deletion from a BST
// (3) Test for no right child
else if (*leaf)->right == NULL) {
deleted = *leaf;
*leaf = (*leaf)->left;
deleted->left = NULL;
free(deleted);
}

// (4) There are two children:


// Retrieve and delete the inorder
successor
else {
(*leaf)->key_value = processLeftmost((*leaf)->right);
}
}
Deletion from a BST
int processLeftmost(struct node **leaf){

if ((*leaf)->left == NULL) {
int key = (*leaf)->key_value;
struct node *deleted = *leaf;
*leaf = (*leaf)->right;
deleted->right = NULL; // defense
free(deleted);
return key;
}
else
return processLeftmost((*leaf)->left);
}
Efficiency of Binary Search Tree
Operations

• The Big O for the retrieval, insertion, removal, and traversal


operations of the ADT binary search tree

Data Structures and Problem Solving with C++: Walls and Mirrors, Carrano and Henry, © 2013
Saving a BST into a file and
restoring it to its original shape
• Save:
– Use a preorder traversal to save the nodes of the BST into a file

• Restore:
– Start with an empty BST
– Read the nodes from the file one by one and insert
them into the BST
Saving a BST into a file and
restoring it to its original shape

Preorder: 60 20 10 40 30 50 70
Saving a BST into a file and
restoring it to a minimum-height BST
• Save:
– Use an inorder traversal to save the nodes of the BST into a file. The
saved nodes will be in ascending order
– Save the number of nodes (n) in somewhere

• Restore:
– Read the number of nodes (n)
– Start with an empty BST
– Read the nodes from the file one by one to create a minimum-
height binary search tree
Building a minimum-height
BST
// Builds a minimum-height binary search tree from n sorted
// values in a file. treePtr will point to the tree’s root.
readTree(out treePtr:TreeNodePtr, in n:integer)

if (n>0) {
treePtr = pointer to new node with NULL child pointers

// construct the left subtree


readTree(treePtr->leftChildPtr, n/2)

// get the root


Read item from file into treePtr->item

// construct the right subtree


readTree(treePtr->rightChildPtr, (n-1)/2)
}
A full tree saved in a file by using inorder traversal
A General Tree
A Pointer-Based Implementation of General Trees
A Pointer-Based Implementation of General
Trees

A pointer-based implementation of
a general tree can also represent
a binary tree.
N-ary
Tree
An n-ary tree is a generalization of a binary whose
nodes each can have no more than n children.

You might also like