Data Structures - Intercollege Cyprus

Download Report

Transcript Data Structures - Intercollege Cyprus

Andreas Savva
Data Structures
Chapter 10
Binary Trees
Lists vs Trees

Lists have great advantages of flexibility but the
have one week feature:


They are sequential lists – can move through them
only one position at a time.
Trees


Valuable for a range of applications, especially for
problems of information retrieval.
The are not sequential.
2
Binary Trees

A binary tree is either empty or it consists of a node
called a root together with two binary trees called the
left subtree and the right subtree of the root.
Amy Ann Dot Eva Guy Jan Jim Jon Kay Kim Ron Roy Tim Tom
Jim
Dot
Amy
Ann
Ron
Guy
Eva
Jan
Kay
Jon
Kim
Tim
Roy
Tom
3
Binary Trees
root
left
root
right
Binary Trees Examples:
3 nodes
2 nodes
Incorrect
4
Nodes

Let x + y mean that the root has x nodes on the
left and y nodes on the right, then
2+0
1+1
0+2
5
Traversal of Binary Trees



Traversal means “moving through all the nodes visiting
each one in turn”.
It is one of the most important operations on binary trees.
There are many different orders in which all the nodes
could be traversed.
V – visiting a node (root)
L – traversing the left subtree (left)
R – traversing the right subtree (right)
VLR
LVR
LRV
preorder
inorder
postorder
VRL
RVL
RLV
mirror images
6
Examples
1
2
1
2
3
Preorder: 1, 2, 3
Inorder:
2, 1, 3
Postorder: 2, 3, 1
1
3
4
5
2
4
5
Preorder: 1, 2, 3, 4, 5
Inorder:
1, 4, 3, 5, 2
Postorder: 4, 5, 3, 2, 1
3
Preorder: 1, 5, 2, 4, 3
Inorder:
5, 1, 4, 2, 3
Postorder: 5, 4, 3, 2, 1
7
Examples (continue)
Jim
Dot
Amy
Ann
Ron
Guy
Eva
Jan
Kay
Jon
Kim
Tim
Roy
Tom
Preorder: Jim, Dot, Amy, Ann, Guy, Eva, Jan, Ron, Kay, Jon, Kim, Tim, Roy, Tom
Inorder: Amy, Ann, Dot, Eva, Guy, Jan, Jim, Jon, Kay, Kim, Ron, Roy, Tim, Tom
Postorder: Ann, Amy, Eva, Jan, Guy, Dot, Jon, Kim, Kay, Roy, Tom, Tim, Ron, Jim
8
Expression Trees
+
!
log
a
b
n
x
Preorder: log x
Inorder:
log x
Postorder: x log
Preorder: + a b
Inorder:
a+b
Postorder: a b +
Preorder: ! n
Inorder:
n!
Postorder: n !
or
–
a
×
b
<
c
Preorder: – a × b c
Inorder:
a–b×c
Postorder: a b c × –
a
<
b
c
d
Preorder: or < a b < c d
Inorder:
a < b or c < d
Postorder: a b < c d < or
9
=
/
X
×
+
2

–
–
b
0.5
×

b
×
2
4
a
c
Related to the Polish form
Preorder – Prefix
Inorder – Infix
Postorder – Postfix
a
Preorder: = X / + – b  –  b 2 × × 4 a c 0.5 × 2 a
Inorder: X = ( – b + ( b  2 – 4 × a × c)  0.5 ) / ( 2 × a)
Postorder: X b – b 2  4 a × c × – 0.5  + 2 a × / =
10
The Node Implementation
template<class Entry>
struct Node {
// data members
Entry entry;
Node<Entry> *left, *right;
// constructors
Node();
Node(const Entry &x);
};
template<class Entry>
Node<Entry>::Node() {
left = right = NULL;
}
template<class Entry>
Node<Entry>::Node(const Entry &x) {
entry = x;
left = right = NULL;
}
11
Linked Implementation of Binary Trees
Jim
Dot
Ron
Amy
Guy
Ann
Eva
Kay
Jan
Jon
Tim
Kim
Roy
Tom
12
The Tree Implementation
template <class Entry>
class Tree {
public:
Tree();
void clear();
bool empty() const;
int size() const;
int height() const;
void preorder(void (*visit)(Entry &));
void inorder(void (*visit)(Entry &));
void postorder(void (*visit)(Entry &));
Error_code insert(const Entry &x);
Error_code remove(const Entry &x);
// Safequards
~Tree();
Tree(const Tree<Entry> &original);
void operator = (const Tree<Entry> &original);
protected:
int size_recursive(Node<Entry> *sub_root) const;
int height_recursive(Node<Entry> *sub_root) const;
void recursive_preorder(Node<Entry> *sub_root, void(*visit)(Entry &));
void recursive_inorder(Node<Entry> *sub_root, void(*visit)(Entry &));
void recursive_postorder(Node<Entry> *sub_root, void(*visit)(Entry &));
Error_code insert_recursive(Node<Entry> * &subroot, const Entry &x);
Error_code remove_recursive(Node<Entry> * &subroot, const Entry &x);
Error_code remove_root(Node<Entry> * &subroot);
Node<Entry> *root;
};
13
Create Tree
Constructor:
template <class Entry>
Tree<Entry>::Tree()
{
root = NULL;
}
root
14
Empty
template <class Entry>
bool Tree<Entry>::empty() const
{
return root == NULL;
}
15
Size
template <class Entry>
int Tree<Entry>::size_recursive(Node<Entry> *sub_root) const
{
if (sub_root == NULL) return 0;
else return 1 + size_recursive(sub_root->left) +
size_recursive(sub_root->right);
}
template <class Entry>
int Tree<Entry>::size() const
{
return size_recursive(root);
}
16
Height
template <class Entry>
int Tree<Entry>::height_recursive(Node<Entry> *sub_root) const
{
if (sub_root == NULL) return 0;
else return 1 + max(height_recursive(sub_root->left),
height_recursive(sub_root->right));
}
template <class Entry>
int Tree<Entry>::height() const
{
return height_recursive(root);
}
17
Preorder
template <class Entry>
void Tree<Entry>::recursive_preorder(Node<Entry> *sub_root,
void(*visit)(Entry &))
{
if (sub_root != NULL) {
(*visit)(subroot->entry);
recursive_preorder(sub_root->left, visit);
recursive_preorder(sub_root->right, visit);
}
}
template <class Entry>
void Tree<Entry>::preorder(void(*visit)(Entry &))
{
recursive_preorder(root, visit);
}
18
Traverse Preorder
void print(int &x)
{
cout << x << endl;
}
the_tree.preorder(print);
Output
1
5
2
4
3
1
5
2
4
3
19
Inorder
template <class Entry>
void Tree<Entry>::recursive_inorder(Node<Entry> *sub_root,
void(*visit)(Entry &))
{
if (sub_root != NULL) {
recursive_inorder(sub_root->left, visit);
(*visit)(subroot->entry);
recursive_inorder(sub_root->right, visit);
}
}
template <class Entry>
void Tree<Entry>::inorder(void(*visit)(Entry &))
{
recursive_inorder(root, visit);
}
20
Postorder
template <class Entry>
void Tree<Entry>::recursive_postorder(Node<Entry> *sub_root,
void(*visit)(Entry &))
{
if (sub_root != NULL) {
recursive_postorder(sub_root->left, visit);
recursive_postorder(sub_root->right, visit);
(*visit)(subroot->entry);
}
}
template <class Entry>
void Tree<Entry>::postorder(void(*visit)(Entry &))
{
recursive_postorder(root, visit);
}
21
The Class Tree
template <class Entry>
class Tree {
public:
.....
void preorder();
void inorder();
void postorder();
.....
protected:
.....
void recursive_preorder(Node<Entry> *sub_root);
void recursive_inorder(Node<Entry> *sub_root);
void recursive_postorder(Node<Entry> *sub_root);
.....
Node<Entry> *root;
};
22
Display Preorder
template <class Entry>
void Tree<Entry>::recursive_preorder(Node<Entry> *sub_root)
{
if (sub_root != NULL) {
cout << subroot->entry << ” ”;
recursive_preorder(sub_root->left);
recursive_preorder(sub_root->right);
}
}
template <class Entry>
void Tree<Entry>::preorder()
{
recursive_preorder(root);
}
23
Display Inorder
template <class Entry>
void Tree<Entry>::recursive_inorder(Node<Entry> *sub_root)
{
if (sub_root != NULL) {
recursive_inorder(sub_root->left);
cout << subroot->entry << ” ”;
recursive_inorder(sub_root->right);
}
}
template <class Entry>
void Tree<Entry>::inorder()
{
recursive_inorder(root);
}
24
Display Postorder
template <class Entry>
void Tree<Entry>::recursive_postorder(Node<Entry> *sub_root)
{
if (sub_root != NULL) {
recursive_postorder(sub_root->left);
recursive_postorder(sub_root->right);
cout << subroot->entry << ” ”;
}
}
template <class Entry>
void Tree<Entry>::postorder()
{
recursive_postorder(root);
}
25
Insert into a Binary Search Tree
Insert: e, b, d, f, a, g, c
Insert: 6, 3, 8, 1, 4, 7, 5, 9, 2
e
b
a
6
f
d
c
3
g
1
8
7
4
2
9
5
Exercises:




Insert:
Insert:
Insert:
Insert:
b, d, f, a, g, c, e
d, c, a, f, g, b, e
1, 2, 3, 4, 5, 6, 7, 8, 9
8, 12, 3, 5, 1, 15, 4, 10, 6, 13, 7, 20, 18, 2, 9, 14
26
Insert
template <class Entry>
Error_code Tree<Entry>::insert_recursive(Node<Entry> *&sub_root, const Entry &x)
{
if (sub_root == NULL)
{
Node<Entry> *temp = new Node<Entry>(x);
if (temp == NULL) return overflow;
sub_root = temp;
return success;
}
else if (x <= sub_root->entry)
return insert_recursive(sub_root->left, x);
else
return insert_recursive(sub_root->right, x);
}
template <class Entry>
Error_code Tree<Entry>::insert(const Entry &x)
{
return insert_recursive(root, x);
}
27
Remove
One subtree empty
Detete x
Deletion of a leaf
Detete x
x
x
Neither subtree empty
Replace x by w
x
w
Delete original w
w
w
w
28
Remove
How can 2 be removed from the tree?
6
6
3
1
3
8
7
4
1
7
4
9
5
2
10
8
10
8
9
5
How can 1 be removed from the tree?
6
6
3
1
7
4
2
3
8
5
10
9
2
8
7
4
5
10
9
29
Remove
How can 6 be removed from the tree?
6
5
5
3
1
8
7
4
10
1
8
7
4
9
5
2
3
10
9
2
How can 3 be removed from the tree?
6
6
3
2
1
7
4
2
2
8
5
10
9
1
8
7
4
5
10
9
30
Remove
How can 9 be removed from the tree?
5
5
9
8
3
1
4
6
10
8
2
8
3
1
4
2
6
10
7
7
31
Remove
template <class Entry>
Error_code Tree<Entry>::remove_recursive(Node<Entry> *&sub_root, const Entry &x)
{
if (sub_root == NULL)
return not_found;
if (sub_root->entry == x)
return remove_root(sub_root);
else if (x < sub_root->entry)
return remove_recursive(sub_root->left, x);
else
return remove_recursive(sub_root->right, x);
}
template <class Entry>
Error_code Tree<Entry>::remove(const Entry &x)
{
return remove_recursive(root, x);
}
32
Remove Root
template <class Entry>
Error_code Tree<Entry>::remove_root(Node<Entry> *&sub_root) {
Node<Entry> *to_delete = sub_root; // remember to delete at end
}
if (sub_root->right==NULL) sub_root = sub_root->left;
else if (sub_root->left == NULL) sub_root = sub_root->right;
else {
// neither subtree is empty.
to_delete = sub_root->left;
// Move left to find predecessor
Node<Entry> *parent = sub_root; // Parent of to_delete
while (to_delete->right != NULL) { // to_delete is not the predecessor
parent = to_delete;
to_delete = to_delete->right;
}
sub_root->entry = to_delete->entry; // Move from to_delete to root
if (parent == sub_root) sub_root->left = to_delete->left;
else parent->right = to_delete->left;
}
delete to_delete;
return success;
33