You are on page 1of 62

DATA STRUCTURES

(PART-III)

SUBRAT//ADA 1
Pre-Requisite
A Tree is a rooted ,acyclic ,directed and connected graph
In Binary Tree each node has at most two children

SUBRAT//ADA 2
In a Max-HEAP for every node i other than the root
A  PARENT  i   A  i 
i.e. the value of a node is at most the value of its parents.

In a Min-HEAP for every node i other than the root


A  PARENT  i   A  i 
i.e. the smallest element in min-heap is at the root.

HEAP is binary tree which satisfies the HEAP PROPERTIES


( Min-HEAP & Max-HEAP ).

Every HEAP is a binary tree but the converse in true.

SUBRAT//ADA 3
HEAP ?????????

The root of the tree is A [1] & for index i of a node the indices
of its parents PARENT (i),left child LEFT (i) & right child RIGHT(i)
can be computed as follows:-
LEFT  i    return 2i 
  i 
PARENT  i    return   
 2 RIGHT  i    return 2i  1 
SUBRAT//ADA 4
The Height of a node in a HEAP defined as the no. of edges on
the longest simple downward path from the node to a leaf &
the height of the heap is height of its root.
Representation of
Heaps

SUBRAT//ADA 5
Suppose given values 1,2,4,6,6,7,8,12,14,15,19,21

SUBRAT//ADA 6
SUBRAT//ADA 7
5 Operations on

Heaps
Maintain the max-heap property
– MAX-HEAPIFY ( O (log n))
• Create a max-heap from an unordered array
– BUILD-MAX-HEAP (linear time)
• Sort an array in place
– HEAPSORT ( O (n log n))
• Allow the Heap data structure to be used as a priority Queue.
– MAX-HEAP-INSERT
– HEAP-EXTRACT- MAX
– HEAP-INCREASE-KEY
– HEAP-MAXIMUM

SUBRAT//ADA 8
Maintaining the Heap Property
In MAX-HEAPIFY the input is an array A & an index i into the
array.
When MAX-HEAPIFY is called it is assumed that the binary tree
rooted as LEFT (i) & RIGHT (i) are max-heaps which may
indicate that A[i] is smaller than its child violating max-heap
property.

The function of MAX-HEAPIFY is to let the value at A[i] “float


down” in the max-heap so that the sub-tree rooted at index i
becomes a max-heap.

SUBRAT//ADA 9
Suppose a node is smaller than a child
Left and Right sub-trees of i are
max-heaps
Invariant:
– the heap condition is violated only
at that node
• To eliminate the violation:
– Exchange with larger child
– Move down the tree
– Continue until node is not smaller
than children

SUBRAT//ADA 10
MAX-HEAPIFY ( A ,
MAX-HEAPIFY (A , i )
i)
Heap Size: Total no of nodes
1. l  LEFT (i)
2. r  RIGHT (i)
3. if l  heap-size [A] and A[l]> A [i]
4. then largest  l
5. else largest  i
6. if r  heap-size [A] and A[r]> A [largest]
7. then largest  r
8. if largest i
9. then exchange A [i]  A [largest]
10. MAX-HEAPIFY (A , largest )

SUBRAT//ADA 11
1 1
2 16 16
3 2
3
i 4 10 14 10
4 5 7 4 5
6 6 7
14 7 9 3 i 4 7 9 3
9 8 9
10 10
2 8 1 2 8 1
1
2 16
3
14 10
4 5 6 7
8 7 9 3

8 9 10
2 4 1
i
SUBRAT//ADA 12
Q: Show that the running time of MAX-HEAPIFY is O( log n).

SUBRAT//ADA 13
Building a Heap
n
• In a complete binary tree the leaf starts from  2   1where n is no. of
 
nodes,where n is length of a tree.
• Convert an array A[1 … n] into a max-heap (n = length[A])
• Apply MAX-HEAPIFY on elements between 1 and n/2

Alg: BUILD-MAX-HEAP(A)
1. Heap-size (A) ← length[A]
2. for i ← n/2 down to 1
3. do MAX-HEAPIFY(A, i)

SUBRAT//ADA 14
Example 1

4
2 3
To make Heapify
1 3
4 5 6 7

8
2 9 10
16 9 10
14 8 7

A: 4 1 3 2 16 9 10 14 8 7

SUBRAT//ADA 15
i =1 5 i=4 i=3
1 1
4
4 4
2 3
2 3 2 3
1 3
4 5 6 7 1 3 1 3
4 5 6 7 4 5 6 7
2 16 9 10
8 9 10
8
2 9 10
16 9 10 8 14 9 10
16 9 10
14 8 7
14 8 7 2 8 7

i=2 i=1
1 1 1

4 4 16
2 3 2 3 2 3

1 10 16 10 14 10
4 5 6 7 4 5 6 7 4 5 6 7

8
14 9 10
16 9 3 8
14 9 10
7 9 3 8
8 9 10
7 9 3
2 8 7 2 8 1 2 4 1

SUBRAT//ADA 16
Running Time of BUILD MAX
HEAP
Alg: BUILD-MAX-HEAP(A)
1. n = length[A]
2. for i ← n/2 down to 1
O(n)
3. do MAX-HEAPIFY(A, i, n) O (lgn)

 Running time: O(nlgn)


• This is not an asymptotically tight upper bound

SUBRAT//ADA 17
• HEAPIFY takes O(h)  the cost of HEAPIFY on a node i is
proportional to the height of the node i in the tree
h h
 T ( n)   ni hi   2i  h  i   O (n)
i 0 i 0

Height Level No. of nodes


h0 = 3 (lgn) i=0 20

h1 = 2 i=1 21

h2 = 1 i=2 22

h3 = 0 i = 3 (lgn) 23

hi = h – i height of the heap rooted at level i


n i = 2i number of nodes at level i
SUBRAT//ADA 18
Heap-sort
• Goal:
– Sort an array using heap representations
• Idea:
– Build a max-heap from the array
– Swap the root (the maximum element) with the last
element in the array
– “Discard” this last node by decreasing the heap size
– Call MAX-HEAPIFY on the new root
– Repeat this process until only one node remains
SUBRAT//ADA 20
HEAPSORT(A)
1. BUILD-MAX-HEAP(A)
O(n)
2. for i ← length[A] down to 2
3. do exchange A[1] ↔ A[i]
4. heap-size[A] ← heap-size [A]-1
n-1 times
5. MAX-HEAPIFY(A, 1)

O(lgn)
• Running time: O(nlgn)

SUBRAT//ADA 21
Example
A: 16 14 10 8 7 9 3 2 4 1

1
16 14
14 10 8 10

8 7 9 3 9 3
4 7
i
2 4 1 2 1 16

a b

SUBRAT//ADA 22
10 9
c d
8 9 8 3

4 7 1 3 4 7 1 2

i i
2 14 16 10 14 16

8 7
e 7 3 f 4 3

i
4 2 1 9 1 2 8 9
i
i i
10 14 16 10 14 16

SUBRAT//ADA 23
4 3
g 2 3 2 1
h
i i
1 7 8 9 4 7 8 9

i i
10 14 16 10 14 16

2
1
i 1 3
i j 2i 3

4 7 8 9
4 7 8 9
i
10 14 16 i
10 14 16

SUBRAT//ADA 24
PRIORITY
QUEUES
A PRIORITY QUEUE is a data structure for maintaining a
set
S of elements each with associated value called a KEY.
• MAX-PRIORITY QUEUES support the following operations:

– INSERT(S, x): inserts element x into set S S  S  x 


– EXTRACT-MAX(S): removes and returns element of S with
largest key

– MAXIMUM(S): returns element of S with largest key

– INCREASE-KEY(S, x, k): increases value of element x’s key to k


(Assume it is as long as x’s current key value)

SUBRAT//ADA 25
HEAP-MAXIMUM Running time: O(1)

Goal:
– Return the largest element of the heap

Alg: HEAP-MAXIMUM(A)
1. return A[1]

Heap A:

Heap-Maximum(A) returns 7

SUBRAT//ADA 26
HEAP-EXTRACT-MAX
Goal:
– Extract the largest element of the heap (i.e., return the max
value and also remove that element from the heap)
Idea:
– Exchange the root element with the last
– Decrease the size of the heap by 1 element
– Call MAX-HEAPIFY on the new root, on a heap of size n-1

Heap A: Root is the largest element

SUBRAT//ADA 27
Alg: HEAP-EXTRACT-MAX(A, n) n: heap size

1. if n < 1 constant

2. then error “heap underflow” constant

3. max ← A[1] constant

4. A[1] ← A[n] constant

5. MAX-HEAPIFY(A, 1) log n

6. return max log n

Running time: O(lgn)

SUBRAT//ADA 28
Example 1
16 max = 16
14 10
14 10
8 7 9 3
8 7 9 3 2 4
2 4 1
Heap size decreased with 1

14
Call MAX-HEAPIFY(A, 1)

8 10
4 7 9 3
2 1

SUBRAT//ADA 29
HEAP-INCREASE-
• Goal: KEY
– Increases the key of an element i in the heap
• Idea:
– Increment the key of A[i] to its new value
– If the max-heap property does not hold anymore:
traverse a path toward the root to find the proper
place for the newly increased key
16

14 10
8 i 7 9 3
Key [i] ← 15 2 4 1
SUBRAT//ADA 30
HEAP-INCREASE-
KEY
Alg: HEAP-INCREASE-KEY(A, i, key)

1. if key < A[i]


2. then error “new key is smaller than current key”
3. A[i] ← key
4. while i > 1 and A[PARENT(i)] < A[i] 16
5. do exchange A[i] ↔ A[PARENT(i)]
14 10
6. i ← PARENT(i)
8 7 9 3
i
2 4 1
• Running time: O(lgn)
Key [i] ← 15
SUBRAT//ADA 31
Example
16 16

14 10 14 10
8 i 7 9 3 8 i 7 9 3
2 4 1 2 15 1

Key [i ] ← 15 i.e index i(4) to be increase 15

16 16
i
14 10 15 10
i
15 7 9 3 14 7 9 3
2 8 1 2 8 1

SUBRAT//ADA 32
MAX-HEAP-
• Goal:
INSERT
16
– Inserts a new element into a max-
heap 14 10

• Idea: 8 7 9 3
2 4 1 -
– Expand the max-heap with a new
element whose key is - 16

– Calls HEAP-INCREASE-KEY to set 14 10


the key of the new node to its 8 7 9 3
correct value and maintain the 2 4 1 15
max-heap property
SUBRAT//ADA 33
MAX-HEAP-INSERT Running time: O(lgn)

16
Alg: MAX-HEAP-INSERT(A, key)
14 10
1. heap-size[A] ← heap-size[A] + 1
8 7 9 3
2. A[heap-size[A] ] ← - 2 4 1 -

3. HEAP-INCREASE-KEY(A, heap-size[A] , key)

SUBRAT//ADA 34
Example
Insert value 15: Increase the key to 15
- Start by inserting - Call HEAP-INCREASE-KEY on A[11] = 15
16 16

14 10 14 10

8 7 9 3 8 7 9 3
2 4 1 - 2 4 1 15

The restored heap containing


the newly added element

16 16

14 10 15 10

8 15 9 3 8 14 9 3

2 4 1 7 2
SUBRAT//ADA 4 1 7 35
Summary
• We can perform the following operations on heaps:
– MAX-HEAPIFY O(lgn)
– BUILD-MAX-HEAP O(n)
– HEAP-SORT O(nlgn)
– MAX-HEAP-INSERT O(lgn)
– HEAP-EXTRACT-MAX O(lgn)
– HEAP-INCREASE-KEY O(lgn)
– HEAP-MAXIMUM O(1)

SUBRAT//ADA 36
The Search
Problem
• Find items with keys matching a given search key
Applications:
• Keeping track of customer account information at a bank
– Search through records to check balances and perform
transactions
• Keep track of reservations on flights
– Search to find empty seats, cancel/modify reservations
• Search engine
– Looks for all documents containing a given word

SUBRAT//ADA 37
Symbol Tables
(Dictionaries)
• Dictionary = data structure that supports two basic
operations: insert a new item and return an item with a
given key
• Queries: return information about the set
– Search (S, k)
– Minimum (S), Maximum (S)
– Successor (S, x), Predecessor (S, x)
• Modifying operations: change the set
– Insert (S, k)
– Delete (S, k)

SUBRAT//ADA 38
Binary Search Trees
• Support many dynamic set operations
– SEARCH, MINIMUM, MAXIMUM, PREDECESSOR,
SUCCESSOR, INSERT
• Running time of basic operations on binary search trees
– On average: (log n)
• The expected height of the tree is log n
– In the worst case: (n)
• The tree is a linear chain of n nodes

SUBRAT//ADA 39
Binary Search Trees
• Tree representation:
– A linked data structure in which each
node is an object
• Node representation:
– Key field
– Satellite data
– Left: pointer to left child
– Right: pointer to right child
– p: pointer to parent (p [root [T]] = NIL)
• Satisfies the binary-search-tree
property
SUBRAT//ADA 40
Binary Search Tree
Example
• Binary search tree property: 5

– If y is in left sub-tree of x, 3 7
then key [y] ≤ key [x] 2 5 9

– If y is in right sub-tree of x,
then key [y] ≥ key [x]

SUBRAT//ADA 41
Traversing a Binary Search
• Inorder tree walk: Tree
– Prints the keys of a binary tree in sorted order
– Root is printed between the values of its left and
right sub-trees: left, root, right
• Preorder tree walk:
– root printed first: root, left, right
• Post-order tree walk: left, right, root
– root printed last
5 Inorder: 2 3 5 5 7 9

3 7 Preorder: 5 3 2 5 7 9
2 5 9 Postorder: 2 5 3 9 7 5
SUBRAT//ADA 42
Traversing a Binary Search
Tree
Alg: INORDER-TREE-WALK(x)
1. if x  NIL
2. then INORDER-TREE-WALK ( left [x] )
3. print key [x]
4. INORDER-TREE-WALK ( right [x] )

• Running time:
 (n), where n is the size of the tree rooted at x
5
Output: 2 3 5 5 7 9
3 7
2 5 9
SUBRAT//ADA 43
Searching for a
• Key
Given a pointer to the root of a tree and a key k:
– Return a pointer to a node with key k 5
if one exists
3 7
– Otherwise return NIL
2 4 9
• Idea
– Starting at the root: trace down a path by comparing
k with the key of the current node:
• If the keys are equal: we have found the key
• If k < key[x] search in the left subtree of x
• If k > key[x] search in the right subtree of x
SUBRAT//ADA 44
Searching for a Key
Alg: TREE-SEARCH(x, k)

1. if x = NIL or k = key [x]


2. then return x
3. if k < key [x]
4. then return TREE-SEARCH(left [x], k )
5. else return TREE-SEARCH(right [x], k )

Running Time: O (h),


h – the height of the tree

SUBRAT//ADA 45
Example: TREE-
SEARCH
15

6 18
• Search for key 13:
3 7 17 20
– 15  6  7  13
2 4 13
9

SUBRAT//ADA 46
Iterative Tree Search (Alternative
Approach)
Alg: ITERATIVE-TREE-SEARCH(x, k)

1. while x  NIL and k  key [x]


2. do if k < key [x]
3. then x  left [x]
4. else x  right [x]
5. return x

SUBRAT//ADA 47
Finding the Minimum in a
Binary Search Tree
• Goal: find the minimum value in a BST
– Following left child pointers from the 15
root, until a NIL is encountered
6 18
Alg: TREE-MINIMUM(x)
1. while left [x]  NIL 3 7 17 20

2. do x ← left [x] 2 4 13
9
3. return x
Minimum = 2
Running time: O(h), h – height of tree

SUBRAT//ADA 48
Finding the Maximum in a Binary
Search Tree
• Goal: find the maximum value in a BST
– Following right child pointers from the root, 15
until a NIL is encountered
Alg: TREE-MAXIMUM(x) 6 18
1. while right [x]  NIL 3 7 17 20
2. do x ← right [x] 2 4 13

3. return x 9

Maximum = 20

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

SUBRAT//ADA 49
Successor
Def: successor (x ) = y, such that key [y] is the
15
smallest key > key [x]
• E.g.: successor (15) =17
successor (13) =15 6 18
successor (9) =13 3 7 17 20
2 4 13
• Case 1: right (x) is non empty
9
– successor (x ) = the minimum in right (x)
• Case 2: right (x) is empty
– go up the tree until the current node is a left child: successor (x )
is the parent of the current node
– if you cannot go further (and you reached the root): x is the
largest element

SUBRAT//ADA 50
Finding the Successor

Alg: TREE-SUCCESSOR(x)
1. if right [x]  NIL
15
2. then return TREE-MINIMUM(right [x])
3. y ← p[x] 6
y
18
4. while y  NIL and x = right [y]
3 7 17 20
5. do x ← y x
2 4 13
6. y ← p[y] 9
7. return y

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


SUBRAT//ADA 51
Predecessor
Def: predecessor (x ) = y, such that key [y] is the
biggest key < key [x] 15
• E.g.: predecessor (15) = 13
predecessor (9) = 7 6 18
predecessor (13) = 9 3 7 17 20
2 4 13
• Case 1: left (x) is non empty 9

– predecessor (x ) = the maximum in left (x)


• Case 2: left (x) is empty
– go up the tree until the current node is a right child:
predecessor (x ) is the parent of the current node
– if you cannot go further (and you reached the root):
x is the smallest element
SUBRAT//ADA 52
Insertion
• Goal: Insert value 13
– Insert value v into a binary search tree 12
• Idea:
5 18
– If key [x] < v move to the right child of x,
else move to the left child of x 2 9 15 19

– When x is NIL, we found the correct position 1 3 13 17

– If v < key [y] insert the new node as y’s left child
else insert it as y’s right child

– Begining at the root, go down the tree and maintain:


• Pointer x : traces the downward path (current
node)
• Pointer y : parent of x (“trailing pointer” )
SUBRAT//ADA 53
Example: TREE-INSERT
x, y=NIL y
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 y
5 18 5 18
2 9 15 19 2 9 15 19
1 3 17 1 3 13 17
x = NIL
y = 15
SUBRAT//ADA 54
Alg: TREE-INSERT(T, v)
1. y ← NIL
2. x ← root [T]
3. while x ≠ NIL 12
4. do y ← x
5. if key [v] < key [x] 5 18

6. then x ← left [x] 2 9 15 19


7. else x ← right [x] 1 3 13 17
8. p[v] ← y
9. if y = NIL
10. then root [T] ← v else if key [v] < key [y]
11. then left [y] ← v
12. else right [y] ← v
Running time: O(h)
SUBRAT//ADA 55
Deletion
• Goal:
– Delete a given node z from a binary search tree
• Idea:
– Case 1: z has no children
• Delete z by making the parent of z point to NIL, instead of to z

15 15

5 16 5 16

3 12 20 3 12 20
z
10 13 18 23 10 18 23

6 delete 6

7 SUBRAT//ADA 7 56
Deletion
• Case 2: z has one child
– Delete z by making the parent of z point to z’s child,
instead of to z
– Update the parent of z’s child to be z’s parent

15 delete 15
z
5 16 5 20

3 12 20 3 12 18 23

10 13 18 23 10

6 6

7 7

SUBRAT//ADA 57
Deletion
• Case 3: z has two children
– z’s successor (y) is the minimum node in z’s right subtree
– y has either no children or one right child (but no left child)
– Delete y from the tree (via Case 1 or 2)
– Replace z’s key and satellite data with y’s.

6 15 15
delete z
5 16 6 16

3 12 20 3 12 20

10 13 18 23 10 13 18 23

y 6 7
SUBRAT//ADA 58
7
Idea for TREE-DELETE(T, z)
• Determine a node y that has to be deleted
– If z has only 1 child  y = z (case 2)
– If z has 2 children  y = TREE-SUCCESSOR(z) (case 3)
– In any case y has at most 1 child!!!
• Set a node x to the non-nil child of y
• Delete node y: set the parent of x to be the parent of y
• If the y is the root x becomes the new root
otherwise, update parent pointers accordingly
• If the deleted node was the successor of z: move y’s key
and satellite data onto z
• The deleted node y is returned for recycling
SUBRAT//ADA 59
TREE-DELETE(T, z)
1. if left[z] = NIL and right[z] = NIL
2. then y ← z z has one child
3. else y ← TREE-SUCCESSOR(z) z has 2 children
4. if left[y]  NIL
15 y
5. then x ← left[y]
5 16
6. else x ← right[y] x
3 12 20
7. if x  NIL
10 13 18 23
8. then p[x] ← p[y]
6

7
SUBRAT//ADA 60
TREE-DELETE(T, z)
9. if p[y] = NIL 15 y

10. then root[T] ← x 5 16


x
11. else if y = left[p[y]] 3 12 20

12. then left[p[y]] ← x 10 13 18 23

13. else right[p[y]] ← x 6

14. if y  z 7

15. then key[z] ← key[y]


16. copy y’s satellite data into z
17. return y

SUBRAT//ADA 61
Binary Search Trees - Summary
• Operations on binary search trees:
– SEARCH O(h)
– PREDECESSOR O(h)
– SUCCESOR O(h)
– MINIMUM O(h)
– MAXIMUM O(h)
– INSERT O(h)
– DELETE O(h)
• These operations are fast if the height of the tree is
small – otherwise their performance is similar to that of
a linked list
SUBRAT//ADA 62
I. HS

II. HIC

III. HM

IV. MHI

V. BMH

VI. MH

VII.HEM

SUBRAT//ADA 63

You might also like