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

Lecture 5

Lecture notes

Uploaded by

Lin Cong
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Lecture 5

Lecture notes

Uploaded by

Lin Cong
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Lecture 5: Dictionaries

School of Computer Science and


Engineering

Fairleigh Dickinson University -


Vancouver

Slides are mainly originate from Dr. Steven Skiena’s course on Analysis of Algorithms
Topic: Binary Search Trees

2
Binary Search Trees
Binary search trees provide a data structure which efficiently
supports all six dictionary operations.
A binary tree is a rooted tree where each node contains at
most two children.
Each child can be identified as either a left or right child.

3
Binary Search Trees
A binary search tree labels each node x in a binary tree such
that all nodes in the left subtree of x have keys < x and all
nodes in the right subtree of x have keys > x.
2

6 8

The search tree labeling enables us to find where any key is.
4
Implementing Binary Search Trees

typedef struct tree {


item_type item; /* data item */
struct tree *parent; /* pointer to parent */
struct tree *left; /* pointer to left child */
struct tree *right; /* pointer to right child */
} tree;

The parent link is optional, since we can usually store the


pointer on a stack when we encounter it.

5
Searching in a Binary Tree: Implementation

tree *search_tree(tree *l, item_type x) {


if (l == NULL) {
return(NULL);
}

if (l->item == x) {
return(l);
}

if (x < l->item) {
return(search_tree(l->left, x));
} else {
return(search_tree(l->right, x));
}
}

6
Searching in a Binary Tree: How Much Time?
The algorithm works because both the left and right subtrees
of a binary search tree are binary search trees – recursive
structure, recursive algorithm.
This takes time proportional to the height of the tree, O(h).

7
Questions?

8
Topic: Operations on Binary Search Trees

9
Maximum and Minimum
Where are the maximum and minimum elements in a binary
search tree?

10
Finding the Minimum

tree *find_minimum(tree *t) {


tree *min; /* pointer to minimum */

if (t == NULL) {
return(NULL);
}

min = t;
while (min->left != NULL) {
min = min->left;
}
return(min);
}

Finding the max or min takes time proportional to the height


of the tree, O(h).

11
Where is the Predecessor?: Internal Node

PREDECESSOR(X) SUCCESSOR(X)

If X has two children, its predecessor is the maximum value


in its left subtree and its successor the minimum value in its
right subtree.

12
Where is the Successor?: Leaf Node

predecessor(x)

If it does not have a left child, a node’s predecessor is its first


left ancestor.
The proof of correctness comes from looking at the in-order
traversal of the tree.
13
In-Order Traversal

H
void traverse_tree(tree *l) {
if (l != NULL) { A

traverse_tree(l->left); F
process_item(l->item);
B G
traverse_tree(l->right);
} D
}
C E

This traversal visits the nodes in A BC DEFGH order.


Because it spends O(1) time at each of n nodes in the tree,
the total time is O(n).

14
Questions?

15
Topic: Insertion and Deletion

16
Tree Insertion
Do a binary search to find where it should be, then replace the
termination NIL pointer with the new item.

Insertion takes time proportional to tree height, O(h).

17
Tree Insertion Code

void insert_tree(tree **l, item_type x, tree *parent) {


tree *p; /* temporary pointer */

if (*l == NULL) {
p = malloc(sizeof(tree));
p->item = x;
p->left = p->right = NULL;
p->parent = parent;
*l = p;
return;
}

if (x < (*l)->item) {
insert_tree(&((*l)->left), x, *l);
} else {
insert_tree(&((*l)->right), x, *l);
}
}

18
Tree Deletion
Deletion is trickier than insertion, because the node to die
may not be a leaf, and thus effect other nodes.
There are three cases:
• Case (a), where the node is a leaf, is simple - just NIL out
the parents child pointer.
• Case (b), where a node has one chld, the doomed node
can just be cut out.
• Case (c), relabel the node as its successor (which has at
most one child when z has two children!) and delete the
successor!
19
Cases of Deletion

2 2 2 2

1 7 1 7 1 7 1 7

4 8 4 8 4 8 5 8

3 6 6 3 5 3 6

5 5

initial tree delete leaf node (3) delete node with 1 child (6) delete node with 2 children (4)

20
Questions?

21
Topic: Balanced Binary Search Trees

22
Binary Search Trees as Dictionaries
All six of our dictionary operations, when implemented with
binary search trees, take O(h), where h is the height of the
tree.
The best height we could hope to get is lg n, if the tree was
perfectly balanced, since

But if we get unlucky with our order of insertion or deletion,


we could get linear height!

23
Tree Insertion: Worst Case Height

insert(a) A

insert(b) B
insert(c)
insert(d) C

If we are unlucky in the order of insertion, and take no steps


to rebalance, the tree can have height Θ(n).

24
Tree Insertion: Average Case Analysis
In fact, binary search trees constructed with random insertion
orders on average have Θ(lg n) height.
Why? Because half the time the insertion will be closer to the
median key than an end key.
Our future analysis of Quicksort will explain more precisely
why the expected height is Θ(lg n).

25
Perfectly Balanced Trees
Perfectly balanced trees require a lot of work to maintain:
9

5 13

3 7 11 15

2 4 6 8 10 12 14

If we insert the key 1, we must move every single node in the


tree to rebalance it, taking Θ(n) time.

26
Balanced Search Trees
Therefore, when we talk about “balanced” trees, we mean
trees whose height is O(lg n), so all dictionary operations
(insert, delete, search, min/max, successor/predecessor) take
O(lg n) time.
No data structure can be better than Θ(lg n) in the worst case
on all these operations.
Extra care must be taken on insertion and deletion to
guarantee such performance, by rearranging things when they
get too lopsided.
Red-Black trees, AVL trees, 2-3 trees, splay trees, and B-trees
are examples of balanced search trees used in practice and
discussed in most data structure texts.
27
Where Does the Log Come From?
Often the logarithmic term in an algorithm analysis comes
from using a balanced search tree as a dictionary, and
performing many (say, n) operations on it.
But often it comes from the idea of a balanced binary tree,
partitioning the items into smaller and smaller subsets, and
doing little work on each of log(n) levels.
Think binary search.

28
Questions?

29

You might also like