0% found this document useful (0 votes)
11 views8 pages

DSA Lab 07

This document outlines a lab session focused on heap data structures and priority queues, detailing objectives, learning outcomes, and implementations of binary max-heaps and min-heaps. It includes code examples for heap operations such as insertion, extraction, and priority queue management, along with practical tasks for students to implement. The lab aims to enhance understanding of heap properties and their applications in computer science.

Uploaded by

Abdullah Shaheer
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)
11 views8 pages

DSA Lab 07

This document outlines a lab session focused on heap data structures and priority queues, detailing objectives, learning outcomes, and implementations of binary max-heaps and min-heaps. It includes code examples for heap operations such as insertion, extraction, and priority queue management, along with practical tasks for students to implement. The lab aims to enhance understanding of heap properties and their applications in computer science.

Uploaded by

Abdullah Shaheer
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/ 8

Data Structures and Algorithms (CS-210)

Lab Session-07
Heap Data Structures and Priority Queues
Dr. M. Abbas Abbasi

1 Objective
Understanding heap data structures and their implementation as priority queues.

2 Learning Outcomes
After completing this lab session, students will be able to:
• Understand the concept and properties of binary heaps
• Implement min-heaps and max-heaps
• Create priority queues using heaps
• Apply basic heap operations (insertion, deletion, extraction)
• Analyze the time complexity of heap operations

3 Heap Data Structure Overview


A heap is a specialized tree-based data structure that satisfies the heap property:
• In a max-heap, for any node N, the value of N is greater than or equal to the values of its children
• In a min-heap, for any node N, the value of N is less than or equal to the values of its children
Heaps are commonly used to implement priority queues, which allow efficient access to the minimum
or maximum element.

3.1 Heap Properties


• Complete Binary Tree: All levels are fully filled except possibly the last level, which is filled
from left to right
• Heap Property: Follows either min-heap or max-heap property
• Efficient Implementation: Can be implemented using arrays without explicit pointers
• Fast Operations: O(log n) for insertion and deletion, O(1) for finding min/max

3.2 Array Representation


Heaps are typically implemented using arrays, where:
• Root is at index 0 (or 1, depending on implementation)
• For a node at index i:
– Left child is at index 2i + 1
– Right child is at index 2i + 2
– Parent is at index (i-1)/2

1
4 Binary Max-Heap Implementation
1 # include < iostream >
2 # include < vector >
3 using namespace std ;
4

5 class MaxHeap {
6 private :
7 vector < int > heap ;
8

9 // Helper function to get parent index


10 int parent ( int i ) { return ( i - 1) / 2; }
11

12 // Helper function to get left child index


13 int leftChild ( int i ) { return 2 * i + 1; }
14

15 // Helper function to get right child index


16 int rightChild ( int i ) { return 2 * i + 2; }
17

18 // Helper function to maintain heap property ( heapify down )


19 void heapifyDown ( int i ) {
20 int largest = i ;
21 int left = leftChild ( i ) ;
22 int right = rightChild ( i ) ;
23

24 // Compare with left child


25 if ( left < heap . size () && heap [ left ] > heap [ largest ])
26 largest = left ;
27

28 // Compare with right child


29 if ( right < heap . size () && heap [ right ] > heap [ largest ])
30 largest = right ;
31

32 // If largest is not the current node , swap and continue heapifying


33 if ( largest != i ) {
34 swap ( heap [ i ] , heap [ largest ]) ;
35 heapifyDown ( largest ) ;
36 }
37 }
38

39 // Helper function to maintain heap property ( heapify up )


40 void heapifyUp ( int i ) {
41 // If not root and parent is smaller than current node
42 if ( i > 0 && heap [ parent ( i ) ] < heap [ i ]) {
43 swap ( heap [ i ] , heap [ parent ( i ) ]) ;
44 heapifyUp ( parent ( i ) ) ; // Recurse up
45 }
46 }
47

48 public :
49 MaxHeap () {}
50

51 // Insert a new element into the heap


52 void insert ( int key ) {
53 // Add the new key at the end
54 heap . push_back ( key ) ;
55

56 // Fix the max heap property if violated


57 int index = heap . size () - 1;
58 heapifyUp ( index ) ;
59 }
60

61 // Extract the maximum element

2
62 int extractMax () {
63 if ( heap . empty () ) {
64 cout << " Heap is empty ! " << endl ;
65 return -1;
66 }
67

68 // Store the max value to return


69 int max = heap [0];
70

71 // Replace root with last element and remove last element


72 heap [0] = heap . back () ;
73 heap . pop_back () ;
74

75 // Restore max heap property


76 if (! heap . empty () )
77 heapifyDown (0) ;
78

79 return max ;
80 }
81

82 // Get maximum element without removing it


83 int getMax () {
84 if ( heap . empty () ) {
85 cout << " Heap is empty ! " << endl ;
86 return -1;
87 }
88 return heap [0];
89 }
90

91 // Check if heap is empty


92 bool isEmpty () {
93 return heap . empty () ;
94 }
95

96 // Get size of heap


97 int size () {
98 return heap . size () ;
99 }
100

101 // Print the heap


102 void printHeap () {
103 for ( int i = 0; i < heap . size () ; i ++)
104 cout << heap [ i ] << " " ;
105 cout << endl ;
106 }
107 };
108

109 int main () {


110 MaxHeap maxHeap ;
111

112 maxHeap . insert (3) ;


113 maxHeap . insert (2) ;
114 maxHeap . insert (15) ;
115 maxHeap . insert (5) ;
116 maxHeap . insert (4) ;
117 maxHeap . insert (45) ;
118

119 cout << " Max Heap : " ;


120 maxHeap . printHeap () ;
121

122 cout << " Maximum element : " << maxHeap . getMax () << endl ;
123

124 cout << " Extracted max : " << maxHeap . extractMax () << endl ;

3
125 cout << " Max Heap after extraction : " ;
126 maxHeap . printHeap () ;
127

128 return 0;
129 }
Listing 1: Max-Heap Implementation

5 Binary Min-Heap and Priority Queue


1 # include < iostream >
2 # include < vector >
3 using namespace std ;
4

5 class MinHeap {
6 private :
7 vector < int > heap ;
8

9 int parent ( int i ) { return ( i - 1) / 2; }


10 int leftChild ( int i ) { return 2 * i + 1; }
11 int rightChild ( int i ) { return 2 * i + 2; }
12

13 void heapifyDown ( int i ) {


14 int smallest = i ;
15 int left = leftChild ( i ) ;
16 int right = rightChild ( i ) ;
17

18 if ( left < heap . size () && heap [ left ] < heap [ smallest ])
19 smallest = left ;
20

21 if ( right < heap . size () && heap [ right ] < heap [ smallest ])
22 smallest = right ;
23

24 if ( smallest != i ) {
25 swap ( heap [ i ] , heap [ smallest ]) ;
26 heapifyDown ( smallest ) ;
27 }
28 }
29

30 void heapifyUp ( int i ) {


31 if ( i > 0 && heap [ parent ( i ) ] > heap [ i ]) {
32 swap ( heap [ i ] , heap [ parent ( i ) ]) ;
33 heapifyUp ( parent ( i ) ) ;
34 }
35 }
36

37 public :
38 MinHeap () {}
39

40 void insert ( int key ) {


41 heap . push_back ( key ) ;
42 int index = heap . size () - 1;
43 heapifyUp ( index ) ;
44 }
45

46 int extractMin () {
47 if ( heap . empty () ) {
48 cout << " Heap is empty ! " << endl ;
49 return -1;
50 }
51

52 int min = heap [0];

4
53 heap [0] = heap . back () ;
54 heap . pop_back () ;
55

56 if (! heap . empty () )
57 heapifyDown (0) ;
58

59 return min ;
60 }
61

62 int getMin () {
63 if ( heap . empty () ) {
64 cout << " Heap is empty ! " << endl ;
65 return -1;
66 }
67 return heap [0];
68 }
69

70 bool isEmpty () {
71 return heap . empty () ;
72 }
73

74 int size () {
75 return heap . size () ;
76 }
77

78 void printHeap () {
79 for ( int i = 0; i < heap . size () ; i ++)
80 cout << heap [ i ] << " " ;
81 cout << endl ;
82 }
83 };
84

85 int main () {
86 MinHeap minHeap ;
87

88 minHeap . insert (5) ;


89 minHeap . insert (2) ;
90 minHeap . insert (8) ;
91 minHeap . insert (1) ;
92 minHeap . insert (10) ;
93

94 cout << " Min Heap : " ;


95 minHeap . printHeap () ;
96

97 cout << " Minimum element : " << minHeap . getMin () << endl ;
98

99 cout << " Elements extracted in order : " ;


100 while (! minHeap . isEmpty () ) {
101 cout << minHeap . extractMin () << " " ;
102 }
103 cout << endl ;
104

105 return 0;
106 }
Listing 2: Min-Heap Implementation

6 Priority Queue Implementation


1 # include < iostream >
2 # include < vector >
3 using namespace std ;

5
4

5 // Priority Queue using Min - Heap


6 class PriorityQueue {
7 private :
8 // Pair of value and priority ( lower priority number = higher priority )
9 vector < pair < int , int > > heap ;
10

11 int parent ( int i ) { return ( i - 1) / 2; }


12 int leftChild ( int i ) { return 2 * i + 1; }
13 int rightChild ( int i ) { return 2 * i + 2; }
14

15 void heapifyDown ( int i ) {


16 int smallest = i ;
17 int left = leftChild ( i ) ;
18 int right = rightChild ( i ) ;
19

20 if ( left < heap . size () && heap [ left ]. second < heap [ smallest ]. second )
21 smallest = left ;
22

23 if ( right < heap . size () && heap [ right ]. second < heap [ smallest ]. second )
24 smallest = right ;
25

26 if ( smallest != i ) {
27 swap ( heap [ i ] , heap [ smallest ]) ;
28 heapifyDown ( smallest ) ;
29 }
30 }
31

32 void heapifyUp ( int i ) {


33 if ( i > 0 && heap [ parent ( i ) ]. second > heap [ i ]. second ) {
34 swap ( heap [ i ] , heap [ parent ( i ) ]) ;
35 heapifyUp ( parent ( i ) ) ;
36 }
37 }
38

39 public :
40 PriorityQueue () {}
41

42 // Insert element with priority


43 void enqueue ( int value , int priority ) {
44 heap . push_back ({ value , priority }) ;
45 int index = heap . size () - 1;
46 heapifyUp ( index ) ;
47 }
48

49 // Extract highest priority element ( lowest priority number )


50 int dequeue () {
51 if ( heap . empty () ) {
52 cout << " Priority Queue is empty ! " << endl ;
53 return -1;
54 }
55

56 int value = heap [0]. first ;


57 heap [0] = heap . back () ;
58 heap . pop_back () ;
59

60 if (! heap . empty () )
61 heapifyDown (0) ;
62

63 return value ;
64 }
65

66 // Get highest priority element without removing

6
67 int peek () {
68 if ( heap . empty () ) {
69 cout << " Priority Queue is empty ! " << endl ;
70 return -1;
71 }
72 return heap [0]. first ;
73 }
74

75 bool isEmpty () {
76 return heap . empty () ;
77 }
78

79 int size () {
80 return heap . size () ;
81 }
82

83 void display () {
84 cout << " Priority Queue contents ( value , priority ) : " << endl ;
85 for ( auto & item : heap ) {
86 cout << " ( " << item . first << " , " << item . second << " ) " ;
87 }
88 cout << endl ;
89 }
90 };
91

92 int main () {
93 PriorityQueue pq ;
94

95 // Enqueue elements with priorities ( lower number = higher priority )


96 pq . enqueue (100 , 3) ; // value 100 with priority 3
97 pq . enqueue (200 , 1) ; // value 200 with priority 1
98 pq . enqueue (300 , 4) ; // value 300 with priority 4
99 pq . enqueue (400 , 2) ; // value 400 with priority 2
100

101 pq . display () ;
102

103 cout << " Highest priority element : " << pq . peek () << endl ;
104

105 cout << " Elements dequeued in order of priority : " ;


106 while (! pq . isEmpty () ) {
107 cout << pq . dequeue () << " " ;
108 }
109 cout << endl ;
110

111 return 0;
112 }
Listing 3: Priority Queue Implementation

7 Lab Tasks
Task 1: Basic Heap Operations
Implement a min-heap supporting the following operations:
• Insert elements
• Extract the minimum element
• Decrease the value of a key at a given index
• Build a heap from an array
Test Cases:

7
1. Insert elements [10, 5, 15, 2, 20]
2. Extract min (should be 2)
3. Decrease the key at index 2 from 15 to 1
4. Extract min (should be 1)
5. Build a heap from [30, 10, 50, 5, 1]
6. Print the resulting min-heap

Task 2: Priority Queue Implementation


Implement a priority queue with the following operations:
• Enqueue element with priority
• Dequeue (extract highest priority element)
• Peek (get highest priority element without removing)
• isEmpty
• size
Test Cases:
1. Create a priority queue
2. Enqueue: (Task A, priority 3), (Task B, priority 1), (Task C, priority 2)
3. Peek (should be Task B)
4. Dequeue (should be Task B)
5. Enqueue: (Task D, priority 1)
6. Dequeue all elements and print them (should be in order: Task D, Task C, Task A)

Task 3: Practical Application


Choose one of the following applications to implement:
Option 1: Process Scheduler
• Create a simple process scheduler using a priority queue
• Each process has an ID, name, and priority
• Implement functions to add processes and execute the highest priority process
• Demonstrate with at least 6 processes of different priorities
Option 2: Top K Elements
• Implement a function to find the k largest elements in an array
• Use a min-heap of size k
• Analyze and explain the time complexity
• Test with different arrays and values of k
Test Cases for Process Scheduler:
1. Add processes with different priorities
2. Execute highest priority process
3. Add more processes during execution
4. Execute all processes and observe the order
Test Cases for Top K Elements:
1. Array: [3, 1, 5, 12, 2, 11], k=3 (should return [5, 11, 12])
2. Array: [5, 15, 10, 20, 8], k=2 (should return [15, 20])
3. Array with duplicate elements

You might also like