0% found this document useful (0 votes)
25 views32 pages

Lec - HeapSort

Uploaded by

emc.javaid2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views32 pages

Lec - HeapSort

Uploaded by

emc.javaid2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Heap Data Structure

Heaps
A (binary) heap data structure is an array of object that can be viewed
as a complete binary tree
A heap is defined only on “nearly full” or complete binary trees. What is
a “nearly full” binary tree?
A complete binary tree is one where all the internal nodes have exactly
2 children, and all the leaves are on the same level. An internal node
comprises all the nodes except the leaf nodes.
Leaf nodes are nodes without children.
Each node of the tree corresponds to an element of the array that
stores the value in the node
The tree is completely filled on all levels except possibly the lowest,
 Interior node
which is filled from left to right up to a point

Edge 

 Leaf node
Heaps
Height of a node: The number of edges starting at that node, and
going down to the furthest leaf.

Height of the heap: The maximum number of edges from the root
to a leaf.  Root

Height of root = 3

Height of blue
node = 1
Heaps
Complete binary tree– if not full, then the only
unfilled level is filled in from left to right.
1 1
2 3 2 3
4 5 6 7 4 5 6
8 9 1 1 1 1 7 8 9 1 1 1
0 1 2 3 0 1 2
Parent(i) Left(i) Right(i)
return i/2 return 2i return 2i + 1
Heap as an Array
● An array A that represents a heap is an array with two attributes
■ length, the number of elements in the array
■ heap-size, the number of heap elements stored in the array
● Viewed as a binary tree and as an array
■ length, the number of elements in the array
Heaps
The heap property of a tree is a condition that must be true
for the tree to be considered a heap.

Min-heap property: for min-heaps, requires


A[parent(i)]  A[i]
So, the root of any sub-tree holds the least value in that
sub-tree.

Max-heap property: for max-heaps, requires


A[parent(i)]  A[i]
The root of any sub-tree holds the greatest value in the
sub-tree.
Heaps

Looks like a max heap, but max-heap property is violated at


indices 11 and 12. Why? because those nodes’ parents have
smaller values than their children.1
9
2
3
8 8
4 5
6 7
8 7 8 1
8 9 10 11 12

6 7 5 8 9
Maintaining the Heap Property
● One of the more basic heap operations is converting a
complete binary tree to a heap.
● Such an operation is called “Heapify”.
● Its inputs are an array A and an index i into the array.
● When Heapify is called, it is assumed that the binary
trees rooted at i.
● LeftChild(i) and RightChild(i) are heaps, but that A[i] may
be smaller than its children, thus violating the 2nd heap
property.
● The function of Heapify is to let the value at A[i] “float
down” in the heap so that the subtree rooted at index i
becomes a heap.
Heaps
Assume we are given a tree represented by a linear array A,
such that i  length[A], and the trees rooted at Left(i) and
Right(i) are heaps. Then, to create a heap rooted at A[i], use
procedure Max-Heapify(A,i):
Max-Heapify(A,i)
1. l  Left(i) 1
0
2. r  Right(i)
2
3. if l  heap-size[A] and A[l] > A[i] 0 9

4. then largest  l
1 1
5. else largest  i 9 8 6 7

6. if r  heap-size[A] and A[r] > A[largest]


1 1 1 1
7. then largest  r 7 6 7 6
1

8. if largest  i
9. then swap( A[i], A[largest])
Heaps
If either child of A[i] is greater than A[i], the greatest child is
exchanged with A[i]. So, A[i] moves down in the heap.
The move of A[i] may have caused a violation of the max-heap
property at it’s new location.
So, we must recursively call Max-Heapify(A,i) at the location i
where the node “lands”.
The above is the top-down approach of Max-Heapify(A,i)
Obviously, Max-Heapify(A,i) can’t be bottom-up. Why?

1
0
2 9
0
1 1 6 7
9 8
1 1 1 1 1
7 6 7 6
Max-Heapify(A,1)
1
2
0
2 0
9 1
0 9
0
1 1 6 7 1 1 6 7
9 8
9 8
1 1 1 1 1
1 1 1 1 1
7 6 7 6
7 6 7 6

2
0 2
1 9 0
0 1 9
1 1 6 7 9
9 8 1 1 6 7
1 1 1 1 1 0 8
7 6 7 6 1 1 1 1 1
7 6 7 6

2 2
0 0
1 9 1 9
9 9
1 1 6 7 1 1 6 7
0 8 7 8
1 1 1 1 1 1 1 1 1 1
7 6 7 6 0 6 7 6
Run Time of Max-Heapify()
Run time of Max-Heapify().
Consider worst case: Last row is half full.
How many nodes, in terms of n, is in the sub-tree with the most nodes?
2n/3
So, worst case would follow a path that included the most nodes
T(n) = T(2n/3) + (1)
Why (1)? Note that all the work in lines 1-7 is simple assignments or
comparisons, so they are constant time, or (1).
1 1 1
2 2 2 3
3
4 5 4 5 6 7
2(2) / 3 = 1
8 9 1 1
2(5) / 3 = 3 0 1
2(11) / 3 = 7
Heaps
So, what must we do to build a heap?
We call Max-Heapify(A,i) for every i starting at last node
and going to the root.
Why Bottom-up?
Because Max-Heapify() moves the larger node upward
into the root. If we start at the top and go to larger
node indices, the highest a node can move is to the root
of that sub-tree. But what if there is a violation between
the sub-tree’s root and its parent?
So, we must start from the bottom and go towards the
root to fix the problems caused by moving larger nodes
into the root of sub-trees.
Heaps
Bad-Build-Max-Heap(A)
1. heap-size[A]  length[A]
2. for i  length[A] downto 1
3. do Max-Heapify(A,i)

Can this implementation be1 improved? Sure can!


2
3

4 5
6 7

8 9 1 1
0 1
Heaps
Without going through a formal proof, notice that there is no
need to call Max-Heapify() on leaf nodes. At most, the
internal node with the largest index is at most equal to
length[A]/2.
Since this may be odd, should we use the floor or the ceiling?

In the case below, it is clear that we really need the floor


of length[A]/2 which is 5, and not the ceiling, which is 6.
1

2 3
Build-Max-Heap(A) 4 5 6 7
1. heap-size[A]  length[A]
8 9 1 1
2. for i  length[A]/2 downto 1 0 1

3. do Max-Heapify(A,i)
Example: building a heap (1)
1 2 3 4 5 6 7 8 9 10
4 1 3 2 16 9 10 14 8 7 1
4
2 3
1 3
4 5 6 7
2 16 9 10

8 9 1
14 8 07
Example: building a heap (2)
1
4
2 3
1 3
4 5 6 7
2 16 9 10

8 9 1
14 8 07
Example: building a heap (3)
1
4
2 3
1 3
4 5 6 7
2 16 9 10

8 9 1
14 8 07
Example: building a heap (4)
1
4
2 3
1 3
4 5 6 7
14 16 9 10

8 9 1
2 8 07
Example: building a heap (5)
1
4
2 3
1 10
4 5 6 7
14 16 9 3

8 9 1
2 8 07
Example: building a heap (6)
1
4
2 3
16 10
4 5 6 7
14 7 9 3

8 9 1
2 8 01
Example: building a heap (7)
1
16
2 3
14 10
4 5 6 7
8 7 9 3

8 9 1
2 4 01
Priority Queues
A priority queue is a data structure for maintaining a set S
of elements, each with an associated value called a key.

We will only consider a max-priority queue.

If we give the key a meaning, such as priority, so that


elements with the highest priority have the highest value of
key, then we can use the heap structure to extract the
element with the highest priority.
Priority queues
We can implement the priority queue ADT
with a heap. The operations are:
● Max(S) – returns the maximum element
● Extract-Max(S) – remove and return the
maximum element
● Insert(x,S) – insert element x into S
● Increase-Key(S,x,k) – increase x’s value
to k
Priority queues: Extract-Max
Heap-Maximum(A) return A[1]
Heap-Extract-Max(A)
1. if heapsize[A] < 1
2. then error “heap underflow”
3. max  A[1]
Make last
4. A[1]  A[heapsize[A]]
element
5. heapsize[A] heapsize[A] –1 the
6. Max-Heapify(A,1) root
7. return max
Priority queues: Increase-Key
Heap-Increase-key(A, i, key)
1. if key < A[i]
2. then error “new key smaller than existing
one”
3. A[i]  key
4. while i > 1 and A[parent(i)] < A[i]
5. do Exchange(A[i], parent(A[i]))
6. i  parent(i)
Priority queues: Insert-Max
Heap-Insert-Max(A, key)
1. heapsize[A] heapsize[A] + 1
2. A[heapsize[A]]  – ∞
3. Heap-Increase-Key(A, heapsize[A],
key)
Example: increase key (1)
1
16
2 3
14 10
4 5 6 7
8 7 9 3

8 9 1
2 4 01 increase 4 to
15
Example: increase key (2)
1
16
2 3
14 10
4 5 6 7
8 7 9 3

8 9 1
2 15 01
Example: increase key (3)
1
16
2 3
14 10
4 5 6 7
15 7 9 3

8 9 1
2 8 01
Example: increase key (4)
1
16
2 3
15 10
4 5 6 7
14 7 9 3

8 9 1
2 8 01

You might also like