This repository has been archived by the owner on Dec 13, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from storopoli/storopoli/intro-search
feat: search algorithms
- Loading branch information
Showing
9 changed files
with
1,191 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"editor.formatOnSave": true, | ||
"tinymist.formatterMode": "typstyle" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <time.h> | ||
|
||
/** | ||
* Function to perform linear search on an array. | ||
* | ||
* @param arr The array to search in. | ||
* @param n The size of the array. | ||
* @param x The target value to search for. | ||
* @return The index of the target if found, otherwise -1. | ||
*/ | ||
int linear_search(int arr[], int n, int x) { | ||
for (int i = 0; i < n; i++) { | ||
if (arr[i] == x) return i; // Element found at position i | ||
} | ||
return -1; // Element not found | ||
} | ||
|
||
/** | ||
* Main function to demonstrate linear search and measure execution time. | ||
*/ | ||
int main() { | ||
int N_values[] = {1000000, 2000000, 4000000, 8000000, 16000000}; | ||
int num_tests = sizeof(N_values) / sizeof(N_values[0]); | ||
|
||
for (int t = 0; t < num_tests; t++) { | ||
int N = N_values[t]; | ||
int *arr = (int *)malloc(N * sizeof(int)); | ||
|
||
// Fill the array with sequential elements | ||
for (int i = 0; i < N; i++) { | ||
arr[i] = i; | ||
} | ||
|
||
// Set the target value to be at the end of the array | ||
// (worst case for linear search) | ||
int target = N - 1; | ||
|
||
// Measure the start time | ||
clock_t start_time = clock(); | ||
|
||
// Perform linear search | ||
int result = linear_search(arr, N, target); | ||
|
||
// Measure the end time | ||
clock_t end_time = clock(); | ||
|
||
// Calculate the elapsed time in seconds | ||
double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; | ||
|
||
// Print the result and time | ||
printf("Linear Search with N = %d\n", N); | ||
if (result != -1) | ||
printf("Target found at index %d\n", result); | ||
else | ||
printf("Target not found\n"); | ||
printf("Time taken: %f seconds\n\n", time_spent); | ||
|
||
// Free the allocated memory | ||
free(arr); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <time.h> | ||
|
||
/** | ||
* Function to perform binary search on a sorted array. | ||
* | ||
* @param arr The sorted array to search in. | ||
* @param n The size of the array. | ||
* @param x The target value to search for. | ||
* @return The index of the target if found, otherwise -1. | ||
*/ | ||
int binary_search(int arr[], int n, int x) { | ||
int left = 0, right = n - 1; | ||
while (left <= right) { | ||
int mid = left + (right - left) / 2; | ||
if (arr[mid] == x) return mid; // Element found | ||
if (arr[mid] < x) | ||
left = mid + 1; | ||
else | ||
right = mid - 1; | ||
} | ||
return -1; // Element not found | ||
} | ||
|
||
/** | ||
* Main function to demonstrate binary search and measure execution time. | ||
*/ | ||
int main() { | ||
int N_values[] = {1000000, 2000000, 4000000, 8000000, 16000000}; | ||
int num_tests = sizeof(N_values) / sizeof(N_values[0]); | ||
|
||
for (int t = 0; t < num_tests; t++) { | ||
int N = N_values[t]; | ||
int *arr = (int *)malloc(N * sizeof(int)); | ||
|
||
// Fill the array with sequential elements | ||
for (int i = 0; i < N; i++) { | ||
arr[i] = i; | ||
} | ||
|
||
// Set the target value to be at the end of the array | ||
// (worst case for linear search) | ||
int target = N - 1; | ||
|
||
// Measure the start time | ||
clock_t start_time = clock(); | ||
|
||
// Perform binary search | ||
int result = binary_search(arr, N, target); | ||
|
||
// Measure the end time | ||
clock_t end_time = clock(); | ||
|
||
// Calculate the elapsed time in seconds | ||
double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; | ||
|
||
// Print the result and time | ||
printf("Binary Search with N = %d\n", N); | ||
if (result != -1) | ||
printf("Target found at index %d\n", result); | ||
else | ||
printf("Target not found\n"); | ||
printf("Time taken: %f seconds\n\n", time_spent); | ||
|
||
// Free the allocated memory | ||
free(arr); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <time.h> | ||
|
||
#define MAX_NODES 50000 // Adjust as needed | ||
|
||
/** | ||
* Node structure for adjacency list | ||
*/ | ||
typedef struct Node { | ||
int vertex; | ||
struct Node* next; | ||
} Node; | ||
|
||
/** | ||
* Graph structure | ||
*/ | ||
typedef struct Graph { | ||
int numVertices; | ||
Node** adjLists; | ||
int* visited; | ||
} Graph; | ||
|
||
/** | ||
* Queue structure for BFS | ||
*/ | ||
typedef struct Queue { | ||
int items[MAX_NODES]; | ||
int front; | ||
int rear; | ||
} Queue; | ||
|
||
/** | ||
* Function to create a node | ||
*/ | ||
Node* createNode(int v) { | ||
Node* newNode = (Node*)malloc(sizeof(Node)); | ||
newNode->vertex = v; | ||
newNode->next = NULL; | ||
return newNode; | ||
} | ||
|
||
/** | ||
* Function to create a graph | ||
*/ | ||
Graph* createGraph(int vertices) { | ||
Graph* graph = (Graph*)malloc(sizeof(Graph)); | ||
graph->numVertices = vertices; | ||
|
||
graph->adjLists = (Node**)malloc(vertices * sizeof(Node*)); | ||
graph->visited = (int*)malloc(vertices * sizeof(int)); | ||
|
||
for (int i = 0; i < vertices; i++) { | ||
graph->adjLists[i] = NULL; | ||
graph->visited[i] = 0; | ||
} | ||
|
||
return graph; | ||
} | ||
|
||
/** | ||
* Function to add edge to an undirected graph | ||
*/ | ||
void addEdge(Graph* graph, int src, int dest) { | ||
// Add edge from src to dest | ||
Node* newNode = createNode(dest); | ||
newNode->next = graph->adjLists[src]; | ||
graph->adjLists[src] = newNode; | ||
|
||
// Since the graph is undirected, add edge from dest to src also | ||
newNode = createNode(src); | ||
newNode->next = graph->adjLists[dest]; | ||
graph->adjLists[dest] = newNode; | ||
} | ||
|
||
/** | ||
* Function to create a queue | ||
*/ | ||
Queue* createQueue() { | ||
Queue* q = (Queue*)malloc(sizeof(Queue)); | ||
q->front = -1; | ||
q->rear = -1; | ||
return q; | ||
} | ||
|
||
/** | ||
* Check if the queue is empty | ||
*/ | ||
int isEmpty(Queue* q) { return q->rear == -1; } | ||
|
||
/** | ||
* Enqueue function | ||
*/ | ||
void enqueue(Queue* q, int value) { | ||
if (q->rear == MAX_NODES - 1) | ||
printf("\nQueue is Full!!"); | ||
else { | ||
if (q->front == -1) q->front = 0; | ||
q->rear++; | ||
q->items[q->rear] = value; | ||
} | ||
} | ||
|
||
/** | ||
* Dequeue function | ||
*/ | ||
int dequeue(Queue* q) { | ||
int item; | ||
if (isEmpty(q)) { | ||
printf("Queue is empty"); | ||
item = -1; | ||
} else { | ||
item = q->items[q->front]; | ||
q->front++; | ||
if (q->front > q->rear) { | ||
// Reset the queue | ||
q->front = q->rear = -1; | ||
} | ||
} | ||
return item; | ||
} | ||
|
||
/** | ||
* BFS algorithm | ||
*/ | ||
void bfs(Graph* graph, int startVertex) { | ||
Queue* q = createQueue(); | ||
|
||
graph->visited[startVertex] = 1; | ||
enqueue(q, startVertex); | ||
|
||
while (!isEmpty(q)) { | ||
int currentVertex = dequeue(q); | ||
|
||
Node* temp = graph->adjLists[currentVertex]; | ||
|
||
while (temp) { | ||
int adjVertex = temp->vertex; | ||
|
||
if (graph->visited[adjVertex] == 0) { | ||
graph->visited[adjVertex] = 1; | ||
enqueue(q, adjVertex); | ||
} | ||
temp = temp->next; | ||
} | ||
} | ||
free(q); | ||
} | ||
|
||
/** | ||
* Main function to demonstrate BFS and measure execution time. | ||
*/ | ||
int main() { | ||
int N_values[] = {1000, 5000, 10000, 20000, 50000}; | ||
int num_tests = sizeof(N_values) / sizeof(N_values[0]); | ||
|
||
for (int t = 0; t < num_tests; t++) { | ||
int N = N_values[t]; | ||
if (N > MAX_NODES) { | ||
printf("N exceeds MAX_NODES limit.\n"); | ||
continue; | ||
} | ||
|
||
Graph* graph = createGraph(N); | ||
|
||
// Build a connected graph (e.g., a chain) | ||
for (int i = 0; i < N - 1; i++) { | ||
addEdge(graph, i, i + 1); | ||
} | ||
|
||
// Measure start time | ||
clock_t start_time = clock(); | ||
|
||
// Perform BFS starting from vertex 0 | ||
bfs(graph, 0); | ||
|
||
// Measure end time | ||
clock_t end_time = clock(); | ||
|
||
// Calculate time taken | ||
double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC; | ||
|
||
// Print the result | ||
printf("BFS with N = %d\n", N); | ||
printf("Time taken: %f seconds\n\n", time_spent); | ||
|
||
// Free memory | ||
for (int i = 0; i < N; i++) { | ||
Node* temp = graph->adjLists[i]; | ||
while (temp) { | ||
Node* toFree = temp; | ||
temp = temp->next; | ||
free(toFree); | ||
} | ||
} | ||
free(graph->adjLists); | ||
free(graph->visited); | ||
free(graph); | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.