0% found this document useful (0 votes)
17 views18 pages

SCP4

The document describes several algorithms including greedy file merge, binary search, merge sort, quicksort, closest pair of points, Karatsuba multiplication, and N queens problem. Code implementations are provided for each algorithm.

Uploaded by

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

SCP4

The document describes several algorithms including greedy file merge, binary search, merge sort, quicksort, closest pair of points, Karatsuba multiplication, and N queens problem. Code implementations are provided for each algorithm.

Uploaded by

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

Optimal File Merge Patterns problem using the Greedy Method:

#include <stdio.h>

#include <stdlib.h>

// Define a structure to represent a file node

struct Node {

int weight;

};

// Define a structure to represent a priority queue (min heap)

struct PriorityQueue {

struct Node* array;

int capacity;

int size;

};

// Function to initialize a new priority queue

struct PriorityQueue* createPriorityQueue(int capacity) {

struct PriorityQueue* pq = (struct PriorityQueue*)malloc(sizeof(struct PriorityQueue));

pq->capacity = capacity;

pq->size = 0;

pq->array = (struct Node*)malloc(capacity * sizeof(struct Node));

return pq;

// Function to swap two nodes in the priority queue

void swap(struct Node* a, struct Node* b) {


struct Node temp = *a;

*a = *b;

*b = temp;

// Heapify function to maintain the heap property of the priority queue

void heapify(struct PriorityQueue* pq, int idx) {

int smallest = idx;

int left = 2 * idx + 1;

int right = 2 * idx + 2;

if (left < pq->size && pq->array[left].weight < pq->array[smallest].weight)

smallest = left;

if (right < pq->size && pq->array[right].weight < pq->array[smallest].weight)

smallest = right;

if (smallest != idx) {

swap(&pq->array[idx], &pq->array[smallest]);

heapify(pq, smallest);

// Function to insert a new node into the priority queue

void insert(struct PriorityQueue* pq, struct Node node) {

if (pq->size == pq->capacity) {

printf("Overflow: Could not insert more elements into the priority queue.\n");

return;

}
pq->size++;

int i = pq->size - 1;

pq->array[i] = node;

while (i != 0 && pq->array[(i - 1) / 2].weight > pq->array[i].weight) {

swap(&pq->array[i], &pq->array[(i - 1) / 2]);

i = (i - 1) / 2;

// Function to extract the minimum node from the priority queue

struct Node extractMin(struct PriorityQueue* pq) {

if (pq->size <= 0) {

struct Node nullNode;

nullNode.weight = -1; // Assuming weight cannot be negative

return nullNode;

if (pq->size == 1) {

pq->size--;

return pq->array[0];

struct Node root = pq->array[0];

pq->array[0] = pq->array[pq->size - 1];

pq->size--;

heapify(pq, 0);

return root;
}

// Function to find the minimum computations needed for optimal file merge pattern

int findOptimalComputation(int files[], int n) {

struct PriorityQueue* pq = createPriorityQueue(n);

// Add all nodes to the priority queue

for (int i = 0; i < n; i++) {

struct Node node;

node.weight = files[i];

insert(pq, node);

int count = 0; // Variable to store file computations

// While there is more than one node in the priority queue

while (pq->size > 1) {

// Create a new node

struct Node newNode;

// Remove the two smallest elements and add their weights to get a new node

newNode.weight = extractMin(pq).weight + extractMin(pq).weight;

// Increment the count with the weight of the new node

count += newNode.weight;

// Add the new node to the priority queue

insert(pq, newNode);

}
// The final count is the answer

return count;

int main() {

// Example usage

int files1[] = {2, 3, 4};

int n1 = sizeof(files1) / sizeof(files1[0]);

printf("Output for files {2, 3, 4}: %d\n", findOptimalComputation(files1, n1));

int files2[] = {2, 3, 4, 5, 6, 7};

int n2 = sizeof(files2) / sizeof(files2[0]);

printf("Output for files {2, 3, 4, 5, 6, 7}: %d\n", findOptimalComputation(files2, n2));

return 0;

Binary Search:
#include <stdio.h>

int binarySearch(int A[], int n, int T) {

int L = 0, R = n - 1;

while (L <= R) {

int m = L + (R - L) / 2;

if (A[m] < T)

L = m + 1;
else if (A[m] > T)

R = m - 1;

else

return m; // Target found

return -1; // Target not found

int main() {

int arr[] = {2, 3, 4, 10, 40};

int n = sizeof(arr) / sizeof(arr[0]);

int target = 10;

int result = binarySearch(arr, n, target);

if (result != -1)

printf("Binary Search: Element %d found at index %d\n", target, result);

else

printf("Binary Search: Element %d not found in the array\n", target);

return 0;

Merge Sort:
#include <stdio.h>

void merge(int A[], int left, int mid, int right) {

int n1 = mid - left + 1;


int n2 = right - mid;

int L[n1], R[n2];

for (int i = 0; i < n1; i++)

L[i] = A[left + i];

for (int j = 0; j < n2; j++)

R[j] = A[mid + 1 + j];

int i = 0, j = 0, k = left;

while (i < n1 && j < n2) {

if (L[i] <= R[j]) {

A[k] = L[i];

i++;

} else {

A[k] = R[j];

j++;

k++;

while (i < n1) {

A[k] = L[i];

i++;

k++;

while (j < n2) {

A[k] = R[j];
j++;

k++;

void mergeSort(int A[], int left, int right) {

if (left < right) {

int mid = left + (right - left) / 2;

mergeSort(A, left, mid);

mergeSort(A, mid + 1, right);

merge(A, left, mid, right);

int main() {

int arr[] = {38, 27, 43, 3, 9, 82, 10};

int n = sizeof(arr) / sizeof(arr[0]);

mergeSort(arr, 0, n - 1);

printf("Merge Sort: Sorted array: ");

for (int i = 0; i < n; i++)

printf("%d ", arr[i]);

printf("\n");

return 0;

}
Quicksort:
#include <stdio.h>

int partition(int A[], int low, int high) {

int pivot = A[high];

int i = low - 1;

for (int j = low; j <= high - 1; j++) {

if (A[j] <= pivot) {

i++;

int temp = A[i];

A[i] = A[j];

A[j] = temp;

int temp = A[i + 1];

A[i + 1] = A[high];

A[high] = temp;

return i + 1;

void quicksort(int A[], int low, int high) {

if (low < high) {

int pi = partition(A, low, high);

quicksort(A, low, pi - 1);


quicksort(A, pi + 1, high);

int main() {

int arr[] = {38, 27, 43, 3, 9, 82, 10};

int n = sizeof(arr) / sizeof(arr[0]);

quicksort(arr, 0, n - 1);

printf("Quicksort: Sorted array: ");

for (int i = 0; i < n; i++)

printf("%d ", arr[i]);

printf("\n");

return 0;

Closest Pair of Points:


#include <stdio.h>

#include <stdlib.h>

#include <math.h>

struct Point {

int x, y;

};
float dist(struct Point p1, struct Point p2) {

return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));

float bruteForce(struct Point P[], int n) {

float min = FLT_MAX;

for (int i = 0; i < n; i++)

for (int j = i + 1; j < n; j++)

if (dist(P[i], P[j]) < min)

min = dist(P[i], P[j]);

return min;

float min(float x, float y) {

return (x < y) ? x : y;

float stripClosest(struct Point strip[], int size, float d) {

float min = d;

qsort(strip, size, sizeof(struct Point), compareY);

for (int i = 0; i < size; i++)

for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < min; j++)

if (dist(strip[i], strip[j]) < min)

min = dist(strip[i], strip[j]);

return min;
}

float closestUtil(struct Point P[], int n) {

if (n <= 3)

return bruteForce(P, n);

int mid = n / 2;

struct Point midPoint = P[mid];

float dl = closestUtil(P, mid);

float dr = closestUtil(P + mid, n - mid);

float d = min(dl, dr);

struct Point strip[n];

int j = 0;

for (int i = 0; i < n; i++)

if (abs(P[i].x - midPoint.x) < d)

strip[j] = P[i], j++;

return min(d, stripClosest(strip, j, d));

float closestPair(struct Point P[], int n) {

qsort(P, n, sizeof(struct Point), compareX);

return closestUtil(P, n);

int main() {
struct Point P[] = {{0, 0}, {1, 1}, {2, 2}, {3, 3}};

int n = sizeof(P) / sizeof(P[0]);

printf("Closest Pair of Points: Distance = %f\n", closestPair(P, n));

return 0;

Karatsuba algorithm for fast multiplication:


#include <stdio.h>

int multiply(int x, int y) {

int size = 1;

while (x > 9 || y > 9) {

x /= 10;

y /= 10;

size *= 10;

return size * (x * y);

int karatsuba(int x, int y) {

if (x < 10 || y < 10)

return multiply(x, y);

int size = 1;
while (x > 9 || y > 9) {

x /= 10;

y /= 10;

size *= 10;

int n = size;

int a = x / n;

int b = x % n;

int c = y / n;

int d = y % n;

int ac = karatsuba(a, c);

int bd = karatsuba(b, d);

int ad_bc = karatsuba((a + b), (c + d)) - ac - bd;

return ac * size * size + ad_bc * size + bd;

int main() {

int x = 1234, y

N Queens problem using backtracking:


#include <stdio.h>

#include <stdlib.h>

// Function to check if placing a queen at the current position is valid


int is_valid(int board[], int row, int col) {

for (int i = 0; i < row; i++) {

if (board[i] == col || abs(board[i] - col) == abs(i - row)) {

return 0; // Invalid placement

return 1; // Valid placement

// Recursive function to solve the N Queens problem

int n_queens(int n, int board[], int row) {

if (row == n) {

// All queens are placed, a solution is found

return 1;

int count = 0;

for (int col = 0; col < n; col++) {

if (is_valid(board, row, col)) {

// Place queen and move to the next row

board[row] = col;

count += n_queens(n, board, row + 1);

return count;

int main() {
int n = 8; // Change the value of 'n' for different board sizes

int board[n];

// Initialize the board

for (int i = 0; i < n; i++) {

board[i] = -1; // No queens placed initially

int solutions = n_queens(n, board, 0);

printf("Number of solutions for %d-Queens problem: %d\n", n, solutions);

return 0;

Flight Itinerary problem using backtracking:


#include <stdio.h>

#include <stdlib.h>

struct Flight {

char origin[4];

char destination[4];

};

// Function to check if adding a flight at the current position is valid

int is_valid(struct Flight *flights, int *used, int current, int n) {

// Check if the flight is unused and its origin matches the last destination
return !used[current] && (current == 0 || strcmp(flights[current].origin, flights[current -
1].destination) == 0);

// Recursive function to solve the Flight Itinerary problem

int get_itinerary(struct Flight *flights, int *used, char **current_itinerary, int current, int n) {

// If we've used up all the flights, we're done

if (current == n) {

return 1;

for (int i = 0; i < n; i++) {

if (is_valid(flights, used, i, n)) {

// Mark the flight as used and add it to the itinerary

used[i] = 1;

strcat(*current_itinerary, flights[i].destination);

// Recursively call with the updated itinerary

if (get_itinerary(flights, used, current_itinerary, current + 1, n)) {

return 1; // Solution found

// Backtrack: remove the flight from the itinerary and mark it as unused

used[i] = 0;

(*current_itinerary)[strlen(*current_itinerary) - 3] = '\0'; // Remove the last destination

return 0; // No valid solution


}

int main() {

struct Flight flights[] = {

{"HNL", "AKL"},

{"YUL", "ORD"},

{"ORD", "SFO"},

{"SFO", "HNL"}

};

int n = sizeof(flights) / sizeof(flights[0]);

int *used = (int *)malloc(n * sizeof(int));

char *current_itinerary = (char *)malloc((4 * n + 1) * sizeof(char));

current_itinerary[0] = '\0';

int found = get_itinerary(flights, used, &current_itinerary, 0, n);

if (found) {

printf("Itinerary: %s\n", current_itinerary);

} else {

printf("No valid itinerary exists.\n");

free(used);

free(current_itinerary);

return 0;

You might also like