I have implemented the K-Way Partitioning algorithm which is based on the Peter Taylor's solution.
Which works but i want fill the q array which is the borders of each pivot. also note that the array of pivots is already given and i need to implement it without the use of std functions.
i think it should be similar to sorted in python(sorted(l,key=lambda x:[x[y]for y in k]) that's not change the pivots and doing it in-place.
The equivalent key function to the python version would be:
[](T* a, T* b) {
for (auto i : pivots) if (a[i] != b[i]) return a[i] < b[i];
return false;
}
please have a look at my test cases because I'm not entirely sure if changing the pivots is OK here in Peter Taylor's solution.
It needs to satisfy this properties at the end:
A[p .. r]
pivots[0 .. (k-1)] an array of k ordered values (in ascending order)
q[0 .. (2k-1)] output array of borders
At the end:
A[p .. q[0]-1] < pivots[0]
A[q[0] .. q[1]-] = pivots[0]
pivots[0] < A[q[1] .. q[2]-1] < pivots[1]
A[q[2] .. q[3]-1] = pivots[1]
...
pivots[i-1] < A[q[2i-1] .. q[2i]-1] < pivots[i] 0 < i < k-1
A[q[2i] .. q[2i+1]-1] = pivots[i] 0 < i < k-1
...
pivots[k-2] < A[q[2k-3] .. q[2k-2]-1] < pivots[k-1]
A[q[2k-2] .. q[2k-1]-1] = pivots[k-1]
A[q[2k-1] .. r] > pivots[k-1]
#pragma once
template <class T>
class KWayPartition {
private:
void swap(T* a, T* b) { T temp = *a; *a = *b; *b = temp; }
int partition(T* A, int low, int high, T* lp,int* q)
{
if (A[low] > A[high]){
swap(&A[low], &A[high]);
}
int j = low + 1;
int g = high - 1, k = low + 1;
T p = A[low], qq = A[high];
while (k <= g) {
if (A[k] < p) {
swap(&A[k], &A[j]);
j++;
}
else if (A[k] >= qq) {
while (A[g] > qq && k < g){
g--;
}
swap(&A[k], &A[g]);
g--;
if (A[k] < p) {
swap(&A[k], &A[j]);
j++;
}
}
k++;
}
j--;
g++;
swap(&A[low], &A[j]);
swap(&A[high], &A[g]);
*lp = j;
return g;
}
void insertionSort(T A[], T r) {
T ki;
int j=0;
for (int i=1;i<r;i++) {
ki = A[i];
j = i - 1;
while (j >= 0 && A[j] > ki) {
A[j+1] = A[j];
j--;
}
A[j+1] = ki;
}
}
void KPartition (T* A, T* pivots,int *q, int p, int r, int sp, int sr) {
if (r<=p) {
return;
}
if (sp<sr) {
insertionSort(A,r);
}
else {
int mid = p+(r-p)/2;
int idx = partition(A, p, r, &pivots[mid],q);
KPartition(A, pivots,q,p, idx - 1,r,mid - 1);
KPartition(A, pivots,q,idx + 1, r ,mid+1,sr);
}
}
public:
virtual void Partition (T* A, T* pivots, int* q, int p, int r, int k) {
KPartition(A, pivots,q, p,r+1, 0,0);
}
};