fixup alt

This commit is contained in:
Jan (janneke) Nieuwenhuizen 2022-10-25 09:06:54 +02:00
parent 63c1ffc468
commit a79d908cda
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
1 changed files with 61 additions and 31 deletions

View File

@ -1,7 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 Paul Dersey <pdersey@gmail.com>
*
* This file is part of GNU Mes.
*
@ -22,47 +21,78 @@
#include <stdlib.h>
void
qswap (void* a, void* b, int size)
qswap (void *a, void *b, size_t size)
{
char buffer[size];
memcpy (buffer, a, size);
memcpy (a, b, size);
memcpy (b, buffer, size);
char *pa = a;
char *pb = b;
do
{
char tmp = *pa;
*pa++ = *pb;
*pb++ = tmp;
} while (--size > 0);
}
size_t
qpart (void *base, size_t low, size_t high, size_t size,
int (*compare) (void const *, void const *))
{
char *pbase = base;
// select the rightmost element as pivot
void *pivot = pbase + high * size;
// pointer for greater element
size_t i = (low - 1);
// traverse each element of the array
// compare them with the pivot
for (int j = low; j < high; j++)
{
int c = compare (pbase + j * size, pivot);
if (c < 0)
{
// if element smaller than pivot is found
// swap it with the greater element pointed by i
i++;
// swap element at i with element at j
void *p1 = pbase + i * size;
void *p2 = pbase + j * size;
qswap (p1, p2, size);
}
}
// swap the pivot element with the greater element at i
void *p1 = pbase + (i + 1) * size;
void *p2 = pbase + high * size;
qswap (p1, p2, size);
// return the qpart point
return (i + 1);
}
void
_qsort (void *base, size_t size, size_t left, size_t right,
int (*compare)(void const*, void const*))
_qsort (void *base, size_t low, size_t high, size_t size,
int (*compare) (void const *, void const *))
{
char *pbase = base;
int mid = (left + right) / 2;
if (left >= right)
if (low >= high)
return;
void *vl = pbase + (left * size);
void *vr = pbase + (mid * size);
qswap (vl, vr, size);
// find the pivot element such that
// elements smaller than pivot are on left of pivot
// elements greater than pivot are on right of pivot
int pi = qpart (base, low, high, size, compare);
int last = left;
for (int i = left + 1; i <= right; i++)
{
void *vt = pbase + (i * size);
if ((*compare)(vl, vt) > 0)
{
++last;
void *v3 = pbase + (last * size);
qswap (vt, v3, size);
}
}
void *v3 = pbase + (last * size);
qswap (vl, v3, size);
_qsort (base, size, left, last - 1, compare);
_qsort (base, size, last + 1, right, compare);
// recursive call on the left of pivot
_qsort (base, low, pi - 1, size, compare);
// recursive call on the right of pivot
_qsort (base, pi + 1, high, size, compare);
}
void
qsort (void *base, size_t count, size_t size,
int (*compare)(void const*, void const*))
int (*compare) (void const *, void const *))
{
_qsort (base, size, 0, count, compare);
_qsort (base, 0, count, size, compare);
}