quicksort
This commit is contained in:
parent
3b1db93d74
commit
45e804a350
7 changed files with 118 additions and 14 deletions
2
TODO.md
2
TODO.md
|
|
@ -4,7 +4,7 @@
|
||||||
- [ ] a tape type - representing a file?
|
- [ ] a tape type - representing a file?
|
||||||
- [x] a record type - x1,x2,x3,x4,x5
|
- [x] a record type - x1,x2,x3,x4,x5
|
||||||
- [x] comparing records
|
- [x] comparing records
|
||||||
- [ ] buffer merge sort
|
- [x] buffer quick sort
|
||||||
- [x] configuration
|
- [x] configuration
|
||||||
- [x] cmd args - man getopts
|
- [x] cmd args - man getopts
|
||||||
- [x] file input
|
- [x] file input
|
||||||
|
|
|
||||||
16
main.c
16
main.c
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "record.h"
|
||||||
|
#include "tape.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -81,7 +83,7 @@ int process_args(int argc, char** argv, options* opts)
|
||||||
fprintf(stderr, "No file specified, aborting\n");
|
fprintf(stderr, "No file specified, aborting\n");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
opts->input = fopen(filename, "a+");
|
opts->input = fopen(filename, "r");
|
||||||
if (!opts->input) {
|
if (!opts->input) {
|
||||||
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
|
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
|
|
@ -99,6 +101,18 @@ void write_file(options* opts)
|
||||||
|
|
||||||
void sort_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)
|
int main(int argc, char** argv)
|
||||||
|
|
|
||||||
15
makefile
15
makefile
|
|
@ -1,5 +1,13 @@
|
||||||
build/main: main.c build
|
CFLAGS = -g
|
||||||
clang main.c -o build/main
|
|
||||||
|
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:
|
build:
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
|
|
@ -10,4 +18,7 @@ clean:
|
||||||
run: build/main
|
run: build/main
|
||||||
build/main -f tests/1.in
|
build/main -f tests/1.in
|
||||||
|
|
||||||
|
debug: build/main
|
||||||
|
lldb -- build/main -f tests/1.in
|
||||||
|
|
||||||
.PHONY: clean run
|
.PHONY: clean run
|
||||||
|
|
|
||||||
16
record.h
16
record.h
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int a[5];
|
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* ra = (const record*)a;
|
||||||
const record* rb = (const record*)b;
|
const record* rb = (const record*)b;
|
||||||
const int ga = g(ra);
|
int ga = g(ra);
|
||||||
const int gb = g(rb);
|
int gb = g(rb);
|
||||||
return (ga > gb) - (ga < gb);
|
int result = (ga > gb) - (ga < gb);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void print_record(FILE* stream, const record* out)
|
static inline void print_record(FILE* stream, const record* out)
|
||||||
{
|
{
|
||||||
fprintf(stream, "[%d %d %d %d %d] x=%d, g=%d",
|
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, g(out));
|
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)
|
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) {
|
if (result == 6) {
|
||||||
|
*out = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (result == EOF) {
|
if (result == EOF) {
|
||||||
|
|
|
||||||
75
tape.c
Normal file
75
tape.c
Normal 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
6
tape.h
|
|
@ -14,11 +14,11 @@ typedef struct {
|
||||||
} buffer;
|
} buffer;
|
||||||
|
|
||||||
// sorts the entire buffer
|
// sorts the entire buffer
|
||||||
void quicksort(buffer* buff);
|
void sort_buffer(buffer* buff);
|
||||||
|
|
||||||
// reads [capacity] records
|
// reads [capacity] records
|
||||||
void read_buffer(buffer* buff, tape* tape);
|
int read_buffer(buffer* buff, tape* tape);
|
||||||
// writes everything
|
// writes everything
|
||||||
void write_buffer(buffer* buff, tape* tape);
|
int write_buffer(buffer* buff, tape* tape);
|
||||||
|
|
||||||
void clear_tape(tape* tape);
|
void clear_tape(tape* tape);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
12312 312312 312 312 323 3
|
11 123 312 312 323 3
|
||||||
543 3435 34 5342 532 54
|
543 3435 34 5342 532 54
|
||||||
344 43534 222 435 2345 23
|
344 43534 222 435 2345 23
|
||||||
2345 234 23423 455 44 4
|
2345 234 23423 455 44 4
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue