mirror of
https://github.com/aicodix/dsp.git
synced 2026-04-27 22:35:45 +00:00
we ain't come this far to omit sorting
This commit is contained in:
parent
c86f767cac
commit
cf60e38b9d
5 changed files with 57 additions and 4 deletions
103
quick.hh
Normal file
103
quick.hh
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Quick algorithms for sorting and selecting
|
||||
|
||||
Copyright 2024 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace DSP {
|
||||
|
||||
namespace QUICK {
|
||||
|
||||
template <typename TYPE>
|
||||
static inline void swap(TYPE *a, int i, int j)
|
||||
{
|
||||
TYPE t = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = t;
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
static inline void median(TYPE *A, int a, int b, int c, int d, int e)
|
||||
{
|
||||
if (A[c] < A[a])
|
||||
swap(A, a, c);
|
||||
if (A[d] < A[b])
|
||||
swap(A, b, d);
|
||||
if (A[d] < A[c]) {
|
||||
swap(A, c, d);
|
||||
swap(A, a, b);
|
||||
}
|
||||
if (A[e] < A[b])
|
||||
swap(A, b, e);
|
||||
if (A[e] < A[c]) {
|
||||
swap(A, c, e);
|
||||
if (A[c] < A[a])
|
||||
swap(A, a, c);
|
||||
} else if (A[c] < A[b]) {
|
||||
swap(A, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
static void partition(TYPE *a, int &l, int &h)
|
||||
{
|
||||
int half = (h - l) / 2;
|
||||
int quarter = (h - l) / 4;
|
||||
int middle = l + half;
|
||||
median(a, l, l + quarter, middle, middle + quarter, h);
|
||||
TYPE pivot = a[middle];
|
||||
for (int i = l; i <= h;)
|
||||
if (a[i] < pivot)
|
||||
swap(a, i++, l++);
|
||||
else if (a[i] > pivot)
|
||||
swap(a, i, h--);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
static void sort(TYPE *a, int l, int h)
|
||||
{
|
||||
if (l < h) {
|
||||
int lt = l, gt = h;
|
||||
partition(a, lt, gt);
|
||||
sort(a, l, lt - 1);
|
||||
sort(a, gt + 1, h);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
static void select(TYPE *a, int l, int h, int k)
|
||||
{
|
||||
while (l < h) {
|
||||
int lt = l, gt = h;
|
||||
partition(a, lt, gt);
|
||||
if (k < lt)
|
||||
h = lt - 1;
|
||||
else if (k > gt)
|
||||
l = gt + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
void quick_sort(TYPE *a, int n)
|
||||
{
|
||||
QUICK::sort(a, 0, n-1);
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
TYPE quick_select(TYPE *a, int k, int n)
|
||||
{
|
||||
assert(n && k < n);
|
||||
QUICK::select(a, 0, n-1, k);
|
||||
return a[k];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue