Quicksort and file rearrange

This commit is contained in:
2025-04-27 18:04:47 +02:00
parent 9180586d50
commit 1c8ab00c13
19 changed files with 316 additions and 168 deletions
+3
View File
@@ -0,0 +1,3 @@
benchmarks/**
dist/**
results.txt
+88
View File
@@ -0,0 +1,88 @@
import subprocess
from random import randint
from time import time, sleep
import matplotlib.pyplot as plt
def run_benchmark(program_name, array):
start = time()
process = subprocess.Popen(program_name, stdin=subprocess.PIPE)
process.communicate((f"{len(array)}\n" + "\n".join(map(str, array))).encode())
if process.returncode == 1:
raise RuntimeError("Error while benchmarking")
end = time()
return end - start
def generate_sequence(sequence_type, array_size):
if sequence_type == "random":
return [randint(0, 100) for i in range(array_size)]
elif sequence_type == "sorted":
return [i for i in range(array_size)]
elif sequence_type == "reversed":
return [i for i in range(array_size, 0, -1)]
elif sequence_type == "constant":
return [5 for i in range(array_size)]
elif sequence_type == "v_shaped":
return [i for i in range(array_size//2, 0, -1)]+[i for i in range(array_size//2)]
else:
raise ValueError("Invalid sequence type")
def plot(program_name, sequences, array_size):
sequence_names = {
"random": "Losowy",
"sorted": "Posortowany",
"reversed": "Odwrócony",
"constant": "Stały",
"v_shaped": "V-kształtny",
}
plt.figure(figsize=(10, 6))
for sequence_type, timings in sequences.items():
plt.plot(array_size, timings, label=sequence_names[sequence_type])
plt.xlabel("Rozmiar tablicy")
plt.ylabel("Czas (ms)")
plt.title(program_name.capitalize())
plt.legend()
plt.savefig(f"./benchmarks/{program_name}.png")
if __name__ == "__main__":
# program_names = ["insertion", "selection", "heapsort", "mergesort"]
program_names = ["heapsort"]
sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"]
array_sizes = [i for i in range(1000, 15001, 1000)]
tests = 10
with open("results.txt", "w") as f:
for program_name in program_names:
if program_name == "heapsort" or program_name == "mergesort":
array_sizes = [i for i in range(15000, 40001, 1000)]
tests = 20
else:
array_sizes = [i for i in range(1000, 15001, 1000)]
tests = 10
sequenceTiming = {
"random": [],
"sorted": [],
"reversed": [],
"constant": [],
"v_shaped": []
}
print(f"Running {program_name}")
for sequence_type in sequence_types:
print(f" - running {sequence_type}")
for array_size in array_sizes:
sequence = generate_sequence(sequence_type, array_size)
durations = []
for i in range(tests):
print(f" - running {sequence_type} with size {array_size} {i+1}/{tests}", end="\r")
duration = run_benchmark(f"./dist/{program_name}", sequence)
duration *= 1000
durations.append(duration)
if program_name == "heapsort" or program_name == "mergesort":
sleep(0.1)
print()
duration = sum(durations) / len(durations)
sequenceTiming[sequence_type].append(duration)
if program_name == "heapsort" or program_name == "mergesort":
sleep(0.1)
plot(program_name, sequenceTiming, array_sizes)
print("Benchmark finished")
+63
View File
@@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
void Heapify(int A[], int i, int heapsize) {
int left = 2 * i;
int right = 2 * i + 1;
int largest = i;
if (left < heapsize && A[left] > A[largest]) {
largest = left;
}
if (right < heapsize && A[right] > A[largest]) {
largest = right;
}
if (largest != i) {
int temp = A[largest];
A[largest] = A[i];
A[i] = temp;
Heapify(A, largest, heapsize);
}
}
void BuildHeap(int A[], int size) {
for (int i = size / 2 - 1; i >= 0; i--) {
Heapify(A, i, size);
}
}
void HeapSort(int A[], int size) {
BuildHeap(A, size);
for (int i = size - 1; i > 0; i--) {
int temp = A[0];
A[0] = A[i];
A[i] = temp;
Heapify(A, 0, i);
}
}
int main() {
int size;
int res = scanf("%d", &size);
if (res != 1) {
fprintf(stderr, "Error reading size\n");
return 1;
}
int *array = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++) {
res = scanf("%d", &array[i]);
if (res != 1) {
fprintf(stderr, "Error reading array element\n");
free(array);
return 1;
}
}
HeapSort(array, size);
free(array);
return 0;
}
+35
View File
@@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
// Capture the pipe of array contents, first number is the size
int main() {
int s;
int res = scanf("%d", &s);
if (res != 1) {
fprintf(stderr, "Error reading size\n");
return 1;
}
int *array = malloc(sizeof(int) * s);
for (int i = 0; i < s; i++) {
res = scanf("%d", &array[i]);
if (res != 1) {
fprintf(stderr, "Error reading array element\n");
free(array);
return 1;
}
}
for (int j = 0; j < s; j++) {
int key = array[j];
int i = j - 1;
while (i >= 0 && array[i] > key) {
array[i + 1] = array[i];
i -= 1;
}
array[i + 1] = key;
}
free(array);
return 0;
}
+53
View File
@@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
void MergeSort(int A[], int l, int r, int B[]) {
int m = (l + r) / 2;
if (m - l > 0) {
MergeSort(A, l, m, B);
}
if (r - m > 0) {
MergeSort(A, m + 1, r, B);
}
int i = l;
int j = m + 1;
for (int k = l; k <= r; k++) {
if ((i <= m && j > r) || ((i <= m && j <= r) && A[i] <= A[j])) {
B[k] = A[i];
i++;
} else {
B[k] = A[j];
j++;
}
}
for (int k = l; k <= r; k++) {
A[k] = B[k];
}
}
int main() {
int size;
int res = scanf("%d", &size);
if (res != 1) {
fprintf(stderr, "Error reading size\n");
return 1;
}
int *arrayA = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++) {
res = scanf("%d", &arrayA[i]);
if (res != 1) {
fprintf(stderr, "Error reading array element\n");
free(arrayA);
return 1;
}
}
int *arrayB = malloc(sizeof(int) * size);
MergeSort(arrayA, 0, size - 1, arrayB);
return 0;
}
+80
View File
@@ -0,0 +1,80 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum PivotStrategy { RIGHTMOST = 0, MIDDLE = 1, RANDOM = 2 };
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int A[], int left, int right, int pivot_strategy, int length) {
int pivot_index;
if (pivot_strategy == RIGHTMOST) {
pivot_index = right;
} else if (pivot_strategy == MIDDLE) {
pivot_index = (left + right) / 2;
} else if (pivot_strategy == RANDOM) {
pivot_index = (rand() % (length + 1));
}
int pivot = A[pivot_index];
swap(&A[pivot_index], &A[right]);
int i = left - 1;
for (int j = left; j < right; j++) {
if (A[j] <= pivot) {
i++;
swap(&A[i], &A[j]);
}
}
swap(&A[i + 1], &A[right]);
return i + 1;
}
void quicksort(int A[], int p, int r, int pivot_strategy, int length) {
if (p < r) {
int q = partition(A, p, r, pivot_strategy, length);
quicksort(A, p, q - 1, pivot_strategy, length);
quicksort(A, q + 1, r, pivot_strategy, length);
}
}
int main() {
int size, pivot_strategy;
if (scanf("%d", &size) != 1) {
fprintf(stderr, "Error reading size\n");
return 1;
}
if (scanf("%d", &pivot_strategy) != 1) {
fprintf(stderr, "Error reading pivot strategy\n");
return 1;
}
// Init the random number generator when needed
if (pivot_strategy == RANDOM) {
srand(size);
}
int *array = malloc(sizeof(int) * size);
if (array == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}
for (int i = 0; i < size; i++) {
if (scanf("%d", &array[i]) != 1) {
fprintf(stderr, "Error reading array element\n");
free(array);
return 1;
}
}
quicksort(array, 0, size - 1, pivot_strategy, size);
free(array);
return 0;
}
+66
View File
@@ -0,0 +1,66 @@
import subprocess
from time import time, sleep
import matplotlib.pyplot as plt
pivot_strategies = {
"rightmost": 0,
"middle": 1,
"random": 2
}
def run_benchmark(array, pivot_strategy):
input_data = f"{len(array)}\n{pivot_strategies[pivot_strategy]}\n" + "\n".join(map(str, array)) + "\n"
start = time()
process = subprocess.Popen("./dist/quicksort", stdin=subprocess.PIPE)
process.communicate(input_data.encode())
if process.returncode != 0:
raise RuntimeError("Error while benchmarking")
end = time()
return end - start
def generate_v_shaped(array_size):
return [i for i in range(array_size // 2, 0, -1)] + [i for i in range(array_size // 2)]
def plot(sequences, array_size):
pivot_names = {
"rightmost": "Pivot prawy",
"middle": "Pivot środkowy",
"random": "Pivot losowy"
}
plt.figure(figsize=(10, 6))
for pivot_type, timings in sequences.items():
plt.plot(array_size, timings, label=pivot_names[pivot_type])
plt.xlabel("Rozmiar tablicy")
plt.ylabel("Czas (ms)")
plt.title("Quicksort")
plt.legend()
plt.savefig("./benchmarks/quicksort.png")
if __name__ == "__main__":
array_sizes = [i for i in range(1000, 15001, 1000)]
with open("results.txt", "w") as f:
sequenceTiming = {
"rightmost": [],
"middle": [],
"random": [],
}
for pivot_strategy in pivot_strategies:
print(f"Running with pivot strategy {pivot_strategy}")
for array_size in array_sizes:
sequence = generate_v_shaped(array_size)
durations = []
for i in range(10):
print(f" - with size of {array_size} {i+1}/10", end="\r")
duration = run_benchmark(sequence, pivot_strategy)
duration *= 1000
durations.append(duration)
sleep(0.1)
print()
duration = sum(durations) / len(durations)
sequenceTiming[pivot_strategy].append(duration)
sleep(0.1)
plot(sequenceTiming, array_sizes)
print("Benchmark finished")
+36
View File
@@ -0,0 +1,36 @@
#include <stdio.h>
#include <stdlib.h>
int main() {
int s;
int res = scanf("%d", &s);
if (res != 1) {
fprintf(stderr, "Error reading size\n");
return 1;
}
int *array = malloc(sizeof(int) * s);
for (int i = 0; i < s; i++) {
res = scanf("%d", &array[i]);
if (res != 1) {
fprintf(stderr, "Error reading array element\n");
free(array);
return 1;
}
}
for (int j = s; j > 1; j--) {
int max = j;
for (int i = j - 1; i >= 0; i--) {
if (array[i] > array[max]) {
max = i;
};
};
int temp = array[j];
array[j] = array[max];
array[max] = temp;
}
free(array);
return 0;
}
+6
View File
@@ -0,0 +1,6 @@
5
12
65
233
87
23