quicksort

This commit is contained in:
bronku 2025-10-15 16:34:25 +02:00
parent 3b1db93d74
commit 45e804a350
7 changed files with 118 additions and 14 deletions

View file

@ -4,7 +4,7 @@
- [ ] a tape type - representing a file?
- [x] a record type - x1,x2,x3,x4,x5
- [x] comparing records
- [ ] buffer merge sort
- [x] buffer quick sort
- [x] configuration
- [x] cmd args - man getopts
- [x] file input

16
main.c
View file

@ -1,3 +1,5 @@
#include "record.h"
#include "tape.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -81,7 +83,7 @@ int process_args(int argc, char** argv, options* opts)
fprintf(stderr, "No file specified, aborting\n");
return ERROR;
}
opts->input = fopen(filename, "a+");
opts->input = fopen(filename, "r");
if (!opts->input) {
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
return ERROR;
@ -99,6 +101,18 @@ void write_file(options* opts)
void sort_file(options* opts)
{
tape a = { 0, 0, opts->input };
buffer buff;
buff.capacity = 100;
buff.location = malloc(sizeof(record) * buff.capacity);
int status = read_buffer(&buff, &a);
if (status != SUCCESS && status != EOF) {
printf("Error reading file: %d\n", status);
}
fclose(a.file);
a.file = stdout;
sort_buffer(&buff);
free(buff.location);
}
int main(int argc, char** argv)

View file

@ -1,5 +1,13 @@
build/main: main.c build
clang main.c -o build/main
CFLAGS = -g
build/main: build/main.o build/tape.o build
clang $(CFLAGS) build/main.o build/tape.o -o build/main
build/main.o: main.c build
clang $(CFLAGS) -c main.c -o build/main.o
build/tape.o: tape.c build
clang $(CFLAGS) -c tape.c -o build/tape.o
build:
mkdir -p build
@ -10,4 +18,7 @@ clean:
run: build/main
build/main -f tests/1.in
debug: build/main
lldb -- build/main -f tests/1.in
.PHONY: clean run

View file

@ -1,5 +1,6 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a[5];
@ -21,21 +22,24 @@ static inline int compare_records(const void* a, const void* b)
{
const record* ra = (const record*)a;
const record* rb = (const record*)b;
const int ga = g(ra);
const int gb = g(rb);
return (ga > gb) - (ga < gb);
int ga = g(ra);
int gb = g(rb);
int result = (ga > gb) - (ga < gb);
return result;
}
static inline void print_record(FILE* stream, const record* out)
{
fprintf(stream, "[%d %d %d %d %d] x=%d, g=%d",
out->a[0], out->a[1], out->a[2], out->a[3], out->a[4], out->x, g(out));
fprintf(stream, "%d %d %d %d %d %d",
out->a[0], out->a[1], out->a[2], out->a[3], out->a[4], out->x);
}
static inline int read_record(FILE* stream, record* out)
{
int result = fscanf(stream, "%d %d %d %d %d %d", &out->a[0], &out->a[1], &out->a[2], &out->a[3], &out->a[4], &out->x);
record tmp;
int result = fscanf(stream, "%d %d %d %d %d %d", &tmp.a[0], &tmp.a[1], &tmp.a[2], &tmp.a[3], &tmp.a[4], &tmp.x);
if (result == 6) {
*out = tmp;
return 0;
}
if (result == EOF) {

75
tape.c Normal file
View file

@ -0,0 +1,75 @@
#include "record.h"
#include "tape.h"
int partition(record* arr, int start, int end)
{
int i = start;
record* pivot = arr;
pivot += end;
for (int j = start; j < end; j++) {
record* current = arr;
current += j;
if (compare_records(current, pivot) > 0) {
continue;
}
record* i_rec = arr;
i_rec += i;
record tmp = *i_rec;
*i_rec = *current;
*current = tmp;
i++;
}
record* i_rec = arr;
i_rec += i;
record tmp = *i_rec;
*i_rec = *pivot;
*pivot = tmp;
return i;
}
void quicksort(record* arr, int start, int end, int depth)
{
if (start >= end || start < 0) {
return;
}
int p = partition(arr, start, end);
quicksort(arr, start, p - 1, depth + 1);
quicksort(arr, p + 1, end, depth + 1);
}
void sort_buffer(buffer* buff)
{
quicksort(buff->location, 0, buff->length - 1, 0);
}
int read_buffer(buffer* buff, tape* tape)
{
int status;
record* destination = buff->location;
buff->length = 0;
while (buff->capacity > buff->length) {
status = read_record(tape->file, destination);
if (status != 0) {
return status;
}
destination++;
buff->length++;
tape->reads++;
}
return 0;
}
int write_buffer(buffer* buff, tape* tape)
{
record* current = buff->location;
record* last = current;
last += buff->length;
while (current < last) {
print_record(tape->file, current);
fprintf(tape->file, "\n");
current++;
tape->reads++;
}
return 0;
}

6
tape.h
View file

@ -14,11 +14,11 @@ typedef struct {
} buffer;
// sorts the entire buffer
void quicksort(buffer* buff);
void sort_buffer(buffer* buff);
// reads [capacity] records
void read_buffer(buffer* buff, tape* tape);
int read_buffer(buffer* buff, tape* tape);
// writes everything
void write_buffer(buffer* buff, tape* tape);
int write_buffer(buffer* buff, tape* tape);
void clear_tape(tape* tape);

View file

@ -1,4 +1,4 @@
12312 312312 312 312 323 3
11 123 312 312 323 3
543 3435 34 5342 532 54
344 43534 222 435 2345 23
2345 234 23423 455 44 4