0% found this document useful (0 votes)
52 views23 pages

Heap Sort and Priority Queue Implementation

The document contains multiple experiments demonstrating various sorting algorithms and data structures in C++ and C. It includes implementations of Heap Sort, Merge Sort, Quick Sort, Hashing with different methods, Disjoint Set using linked list and rooted tree, and graph traversal methods like BFS and DFS. Each experiment provides code snippets and explanations for the respective algorithms and data structures.
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)
52 views23 pages

Heap Sort and Priority Queue Implementation

The document contains multiple experiments demonstrating various sorting algorithms and data structures in C++ and C. It includes implementations of Heap Sort, Merge Sort, Quick Sort, Hashing with different methods, Disjoint Set using linked list and rooted tree, and graph traversal methods like BFS and DFS. Each experiment provides code snippets and explanations for the respective algorithms and data structures.
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

Experiment-8:

 WAP that implements the Heap sort and Priority Queue using Heap:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100 // Maximum size of the heap

// Structure to represent a max heap


typedef struct {
int arr[MAX_SIZE];
int size;
} MaxHeap;

// Function to swap two elements


void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}

// Function to heapify a subtree rooted at index `i`


void maxHeapify(MaxHeap *heap, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;

if (left < heap->size && heap->arr[left] > heap->arr[largest])


largest = left;
if (right < heap->size && heap->arr[right] > heap->arr[largest])
largest = right;

if (largest != i) {
swap(&heap->arr[i], &heap->arr[largest]);
maxHeapify(heap, largest);
}
}

// Function to insert a new key into the max heap


void insert(MaxHeap *heap, int key) {
if (heap->size == MAX_SIZE)
{printf("Heap overflow\n");
return;
}

// Insert the new key at the end and increase the heap size
int i = heap->size++;
heap->arr[i] = key;

// Fix the max heap property if it is violated


while (i != 0 && heap->arr[(i - 1) / 2] < heap->arr[i])
{swap(&heap->arr[i], &heap->arr[(i - 1) / 2]);
i = (i - 1) / 2;
}
}

// Function to get the maximum element (root) from the max heap
int getMax(MaxHeap *heap) {
if (heap->size <= 0)
{ printf("Heap is
empty\n");return -1;
}
return heap->arr[0];
}

// Function to extract the maximum element (root) from the max heap
int extractMax(MaxHeap *heap) {
if (heap->size <= 0)
{ printf("Heap is
empty\n");return -1;
}

int root = heap->arr[0];


heap->arr[0] = heap->arr[--heap->size];
maxHeapify(heap, 0);

return root;
}

// Function to increase the key at index `i` to new_key


void increaseKey(MaxHeap *heap, int i, int new_key) {
if (i < 0 || i >= heap->size || heap->arr[i] > new_key)
{printf("Invalid operation\n");
return;
}

heap->arr[i] = new_key;
while (i != 0 && heap->arr[(i - 1) / 2] < heap->arr[i])
{swap(&heap->arr[i], &heap->arr[(i - 1) / 2]);
i = (i - 1) / 2;
}
}

// Function to delete a key at index `i`


void deleteKey(MaxHeap *heap, int i) {
increaseKey(heap, i, INT_MAX ); // Increase key to infinity
extractMax(heap); // Extract the maximum
}
// Heap Sort function
void heapSort(int arr[], int n)
{MaxHeap heap;
[Link] = 0;

// Insert all elements into the heap


for (int i = 0; i < n; i++)
insert(&heap, arr[i]);

// Extract elements from heap in sorted order


for (int i = n - 1; i >= 0; i--)
arr[i] = extractMax(&heap);
}

// Function to display an array


void displayArray(int arr[], int n) {
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}

// Main function to test the above code


int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: ");


displayArray(arr, n);

// Heap Sort
heapSort(arr, n);
printf("Sorted array using Heap Sort: ");
displayArray(arr, n);

// Priority Queue operations


MaxHeap heap;
[Link] = 0;
insert(&heap, 3);
insert(&heap, 10);
insert(&heap, 15);
insert(&heap, 7);

printf("Max element in the priority queue: %d\n", getMax(&heap));


printf("Extracting max: %d\n", extractMax(&heap));
printf("Max element after extraction: %d\n", getMax(&heap));

return 0;
}
Output:
Experiment-9:

 Write a program that implements the Merge sort.

#include <iostream>
using namespace std;
void merge(int arr[], int left, int mid, int right)
{int n1 = mid - left + 1;
int n2 = right - mid;
int leftArr[n1], rightArr[n2];
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int j = 0; j < n2; j++)
rightArr[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j])
{arr[k] = leftArr[i];
i++;
} else {
arr[k] = rightArr[j];
j++;
}
k++;
}
while (i < n1)
{ arr[k] =
leftArr[i];i++;
k++;
}
while (j < n2) {
arr[k] = rightArr[j];
j++;
k++;
}
}
void mergeSort(int arr[], int left, int right)
{if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
void printArray(int arr[], int size)
{for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}

int main() {
int arr[] = {38, 27, 43, 3, 9, 82, 10};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
printArray(arr, size);
mergeSort(arr, 0, size - 1);
cout << "Sorted array: ";
printArray(arr, size);
return 0;
}

Output:
Experiment-10:

 Write a program that implements the Quick sort.

#include <iostream>
using namespace std;
void swap(int *a, int *b)
{int temp = *a;
*a = *b;
*b = temp;
}
int partition(int *A, int p, int r)
{int i = p, j = p;
while (j < r) {
if (A[j] < A[r]) {
swap(&A[i], &A[j]);
i++;
}
j++;
}
swap(&A[i], &A[r]);
return i;
}
void QuickSort(int *A, int p, int r)
{if (p < r) {
int q = partition(A, p, r);
QuickSort(A, p, q - 1);
QuickSort(A, q + 1, r);
}}
int main() {
int A[] = {34, 56, 23, 1, 2, 0, -1, 7, 22, 100, 21};
int r = sizeof(A) / sizeof(A[0]) - 1;
QuickSort(A, 0, r);
for (int i = 0; i <= r; i++)
{cout << A[i] << "\t";}
cout << endl;
return 0;}

Output:
Experiment-11:
 Write a program that implements the Hashing using different methods.

#include <iostream>
using namespace std;
const int TABLE_SIZE = 10;
class LinearProbingHash {
int *table;
public:
LinearProbingHash() {
table = new int[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = -1; // -1 indicates an empty slot
}
void insert(int key) {
int hash = key % TABLE_SIZE;
int originalHash = hash;
while (table[hash] != -1) {
hash = (hash + 1) % TABLE_SIZE;
if (hash == originalHash) {
cout << "Table is full" << endl;
return;
}
}
table[hash] = key;
}
void display() {
cout << "Linear Probing Table: ";
for (int i = 0; i < TABLE_SIZE; i++)
cout << table[i] << " ";
cout << endl;
}
};
class QuadraticProbingHash
{int *table;
public:
QuadraticProbingHash() {
table = new int[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = -1;
}
void insert(int key) {
int hash = key % TABLE_SIZE;
int i = 0;
while (table[(hash + i * i) % TABLE_SIZE] != -1)
{i++;
if (i == TABLE_SIZE) {
cout << "Table is full" << endl;
return;
}
}
table[(hash + i * i) % TABLE_SIZE] = key;
}
void display() {
cout << "Quadratic Probing Table: ";
for (int i = 0; i < TABLE_SIZE; i++)
cout << table[i] << " ";
cout << endl;
}
};
class DoubleHashingHash
{int *table;
int PRIME;
public:
DoubleHashingHash() {
table = new int[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = -1;
PRIME = 7;
}
int hash1(int key) {
return key % TABLE_SIZE;
}
int hash2(int key) {
return PRIME - (key % PRIME);
}
void insert(int key) {
int hash = hash1(key);
int stepSize = hash2(key);
int i = 0;
while (table[(hash + i * stepSize) % TABLE_SIZE] != -1)
{i++;
if (i == TABLE_SIZE) {
cout << "Table is full" << endl;
return;
}
}
table[(hash + i * stepSize) % TABLE_SIZE] = key;
}
void display() {
cout << "Double Hashing Table: ";
for (int i = 0; i < TABLE_SIZE; i++)
cout << table[i] << " ";
cout << endl;
}
};
int main() {
int keys[] = {23, 43, 13, 27, 10, 33, 19, 29, 25, 17};
int n = sizeof(keys) / sizeof(keys[0]);
LinearProbingHash linearHash;
QuadraticProbingHash quadraticHash;
DoubleHashingHash doubleHash;
for (int i = 0; i < n; i++)
{ [Link](keys[i]);
[Link](keys[i]);
[Link](keys[i]);
}
[Link]();
[Link]();
[Link]();

return 0;
}

Output:
Experiment-12:

 Write a program that implements the disjoint set using link list structure and rootedtree.

include <iostream>
#include <unordered_map>
using namespace std;

class Node
{public:
int data;
Node* parent;
int rank; // Used for union by rank in the tree approach

Node(int data)
{ this->data =
data;
this->parent = this; // Initially, a node is its own parent
this->rank = 0; // Initial rank is zero
}
};

// Disjoint Set using Linked List and Rooted Tree


class DisjointSet {
unordered_map<int, Node*> map;

public:
// Creates a new set with a single element
void makeSet(int data) {
if ([Link](data) != [Link]()) {
cout << "Element " << data << " already exists." << endl;
return;
}
Node* newNode = new Node(data);
map[data] = newNode;
cout << "Set created for element " << data << "." << endl;
}

// Finds the representative (root) of the set containing the element


Node* findSet(int data) {
if ([Link](data) == [Link]()) {
cout << "Element " << data << " not found in any set." << endl;
return nullptr;
}
return findSet(map[data]);
}

// Helper function for findSet with path compression


Node* findSet(Node* node) {
if (node->parent == node)
{ return node; // Root node
found
}
node->parent = findSet(node->parent); // Path compression
return node->parent;
}

// Union of two sets using union by rank


void unionSets(int data1, int data2) {
Node* node1 = findSet(data1);
Node* node2 = findSet(data2);

if (node1 == nullptr || node2 == nullptr) {


cout << "One or both elements not found in any set." << endl;
return;
}

if (node1 == node2) {
cout << "Both elements are in the same set." << endl;
return;
}

// Union by rank
if (node1->rank > node2->rank)
{node2->parent = node1;
} else if (node1->rank < node2->rank)
{node1->parent = node2;
} else {
node2->parent = node1;
node1->rank++;
}
cout << "Sets containing " << data1 << " and " << data2 << " have been merged." << endl;
}

// Display the representative of each set


void displaySets() {
cout << "Current sets and their representatives:" << endl;
for (auto pair : map) {
int element = [Link];
Node* rep = findSet(element);
if (rep) {
cout << "Element " << element << " belongs to set with representative " << rep->data << endl;
}}}};
int main()
{ DisjointSet ds;
// Create sets for individual elements
[Link](1);
[Link](2);
[Link](3);
[Link](4);
[Link](5);
// Display sets before any unions
cout << "\nSets before union operations:" << endl;
[Link]();
// Perform union operations
[Link](1, 2);
[Link](3, 4);
[Link](2, 3);
// Display sets after union operations
cout << "\nSets after union operations:" << endl;
[Link]();
// Find representatives for individual elements
cout << "\nFinding representatives:" << endl;
cout << "Representative of 1: " << [Link](1)->data << endl;
cout << "Representative of 3: " << [Link](3)->data << endl;
cout << "Representative of 5: " << [Link](5)->data << endl;
return 0;}
Output:
Experiment-13:

 Write a program that implements the BFS and DFS

#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
class Graph {
int vertices; // Number of vertices in the graph
vector<list<int>> adjList; // Adjacency list
public:
// Constructor
Graph(int vertices) {
this->vertices = vertices;
[Link](vertices);
}
// Add edge to the graph
void addEdge(int u, int v) {
adjList[u].push_back(v); // Add v to u's list
adjList[v].push_back(u); // Since the graph is undirected
}
// Breadth-First Search (BFS)
void BFS(int start) {
vector<bool> visited(vertices, false);
queue<int> q;
visited[start] = true;
[Link](start);
cout << "BFS starting from vertex " << start << ": ";
while (![Link]()) {
int node = [Link]();
[Link]();
cout << node << " ";
for (auto neighbor : adjList[node])
{if (!visited[neighbor]) {
visited[neighbor] = true;
[Link](neighbor);
}} }
cout << endl;
}
// Depth-First Search (DFS) - Recursive helper
void DFSUtil(int node, vector<bool> &visited) {
visited[node] = true;
cout << node << " ";

for (auto neighbor : adjList[node])


{if (!visited[neighbor]) {
DFSUtil(neighbor, visited);
}}}

// Depth-First Search (DFS) - Main function


void DFS(int start) {
vector<bool> visited(vertices, false);
cout << "DFS starting from vertex " << start << ": ";
DFSUtil(start, visited);
cout << endl;
}};
int main()
{ Graph
g(6);
// Add edges
[Link](0, 1);
[Link](0, 2);
[Link](1, 3);
[Link](2, 4);
[Link](3, 5);
[Link](4, 5);
// Perform BFS and DFS
cout << "Performing BFS and DFS on the graph:" << endl;
[Link](0); // Starting BFS from node 0
[Link](0); // Starting DFS from node 0
return 0;
}

Output:
Experiment-14:

 Write a program that implements the Minimum Spanning Tree via


a) Prim’s algoruthm.
b) Kruskal algorithm.

Code:

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <tuple>
#include <climits> // For INT_MAX

using namespace std;

class Graph
{ int
vertices;
vector<vector<pair<int, int>>> adjList; // For Prim's: Adjacency list with {neighbor, weight}
vector<tuple<int, int, int>> edges; // For Kruskal's: List of edges as {weight, u, v}

public:
Graph(int v) : vertices(v)
{[Link](v);
}

// Adds an undirected edge for Prim's adjacency list and Kruskal's edge list
void addEdge(int u, int v, int weight) {
adjList[u].push_back({v, weight});
adjList[v].push_back({u, weight});
edges.push_back({weight, u, v});
}

// Prim's Algorithm for MST


void primMST() {
vector<int> key(vertices, INT_MAX); // Store minimum edge weight for each vertex
vector<int> parent(vertices, -1); // Store MST structure
vector<bool> inMST(vertices, false); // Track vertices included in MST
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

int mstCost = 0; // To store the total cost of the MST


// Starting with vertex 0
key[0] = 0;
[Link]({0, 0});

cout << "Prim's MST edges (u - v):\n";


while (![Link]()) {
int u = [Link]().second;
int weight = [Link]().first;
[Link]();

if (inMST[u]) continue; // If already in MST, skip


inMST[u] = true;
mstCost += weight; // Add the edge weight to the MST cost

for (size_t i = 0; i < adjList[u].size(); i++)


{int v = adjList[u][i].first;
int edgeWeight = adjList[u][i].second;
if (!inMST[v] && edgeWeight < key[v])
{key[v] = edgeWeight;
[Link]({key[v], v});
parent[v] = u;
}}}

// Print MST edges


for (int v = 1; v < vertices; v++)
{if (parent[v] != -1) {
cout << parent[v] << " - " << v << "\n";
}}
cout << "Total Minimum Cost of Prim's MST: " << mstCost << endl;
}
// Find operation for disjoint set (Union-Find) with path compression
int find(int u, vector<int> &parent) {
if (parent[u] != u) {
parent[u] = find(parent[u], parent);
}
return parent[u];
}
// Union operation for disjoint set (Union-Find) with union by rank
void unionSets(int u, int v, vector<int> &parent, vector<int> &rank) {
int rootU = find(u, parent);
int rootV = find(v, parent);
if (rootU != rootV) {
if (rank[rootU] > rank[rootV])
{parent[rootV] = rootU;
} else if (rank[rootU] < rank[rootV])
{parent[rootU] = rootV;
} else {
parent[rootV] = rootU;
rank[rootU]++;
}}}
// Kruskal's Algorithm for MST
void kruskalMST() {
sort([Link](), [Link]()); // Sort edges by weight
vector<int> parent(vertices);
vector<int> rank(vertices, 0);
for (int i = 0; i < vertices; i++) {
parent[i] = i;
}
int mstCost = 0; // To store the total cost of the MST
cout << "Kruskal's MST edges (u - v) with weights:\n";
for (size_t i = 0; i < [Link](); i++) {
int weight = get<0>(edges[i]);
int u = get<1>(edges[i]);
int v = get<2>(edges[i]);
if (find(u, parent) != find(v, parent)) {
cout << u << " - " << v << " : " << weight << "\n";
mstCost += weight; // Add the edge weight to the MST cost
unionSets(u, v, parent, rank);
}}
cout << "Total Minimum Cost of Kruskal's MST: " << mstCost << endl;
}};
int main()
{ Graph
g(6);
// Adding edges
[Link](0, 1, 4);
[Link](0, 2, 4);
[Link](1, 2, 2);
[Link](1, 3, 6);
[Link](2, 3, 8);
[Link](3, 4, 9);
[Link](4, 5, 10);
[Link](3, 5, 2);
cout << "Minimum Spanning Tree using Prim's Algorithm:\n";
[Link]();
cout << "\nMinimum Spanning Tree using Kruskal's Algorithm:\n";
[Link]();
return 0;}
Output:
Experiment-15:

 AIM: Write a program that implements the Shortest Path Algorithms via
a. Dijkstra’s
b. Bellman-Ford algorithm.
Code:
#include <iostream>
#include <vector>
#include <climits>
#include <queue>
#include <tuple>
using namespace std;
class Graph {
int vertices; // Number of vertices
vector<vector<pair<int, int>>> adjList; // Adjacency list for Dijkstra's algorithm
public:
Graph(int v) : vertices(v)
{[Link](v);
}
// Function to add edges to the graph
void addEdge(int u, int v, int weight) {
adjList[u].emplace_back(v, weight);
adjList[v].emplace_back(u, weight); // For undirected graph
}
// Dijkstra's Algorithm
void dijkstra(int source) {
vector<int> dist(vertices, INT_MAX); // Distance from source
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // Min-heap
dist[source] = 0;
[Link]({0, source}); // {distance, vertex}
cout << "Dijkstra's Algorithm:\n";
while (![Link]()) {
int u = [Link]().second; // Get the vertex with the smallest [Link]();
// Traverse all adjacent vertices
for (const auto& neighbor : adjList[u])
{int v = [Link];
int weight = [Link];
// If a shorter path to v is found
if (dist[u] + weight < dist[v])
{dist[v] = dist[u] + weight;
[Link]({dist[v], v})}}}
// Print the result
for (int i = 0; i < vertices; i++) {
cout << "Distance from source to vertex " << i << " is " << dist[i] << endl;
}
}
// Bellman-Ford Algorithm
void bellmanFord(int source) {
vector<int> dist(vertices, INT_MAX);
dist[source] = 0;
cout << "\nBellman-Ford Algorithm:\n";
for (int i = 1; i < vertices; i++) {
for (int u = 0; u < vertices; u++) {
for (const auto& neighbor : adjList[u])
{int v = [Link];
int weight = [Link];
// Relaxation step
if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
{dist[v] = dist[u] + weight;
}}}}
// Check for negative-weight cycles
for (int u = 0; u < vertices; u++) {
for (const auto& neighbor : adjList[u])
{int v = [Link];
int weight = [Link];
if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
{cout << "Graph contains a negative-weight cycle\n";
return;
}}}
for (int i = 0; i < vertices; i++) {
cout << "Distance from source to vertex " << i << " is " << dist[i] << endl;
}}};
int main() {
Graph g(5); // Create a graph with 5 vertices
[Link](0, 1, 10);[Link](0, 2, 3);[Link](1, 2, 1);[Link](1, 3, 2);[Link](2, 1, 4);
[Link](2, 3, 8);[Link](2, 4, 2);
[Link](3, 4, 7);
g.a ddEdge(4, 3, 9);
int source = 0;
[Link](source);
g.b ellmanFord(source);
return 0;
}
Output:

You might also like