|
| Sort () |
| The default constructor can be used when the data is only passed in via function sortKey . More...
|
|
| Sort (const void *data, uInt elementSize) |
| Construct a Sort object for the given data array with elements of elementSize bytes. More...
|
|
| Sort (const Sort &) |
| Copy constructor (copy semantics). More...
|
|
| ~Sort () |
|
Sort & | operator= (const Sort &) |
| Assignment (copy semantics). More...
|
|
void | sortKey (const void *data, DataType, uInt increment=0, Order=Ascending) |
| Define a sort key (the most significant key should be defined first). More...
|
|
void | sortKey (const void *data, const CountedPtr< BaseCompare > &, uInt increment, Order=Ascending) |
|
void | sortKey (uInt offset, DataType, Order=Ascending) |
|
void | sortKey (uInt offset, const CountedPtr< BaseCompare > &, Order=Ascending) |
|
uInt | sort (Vector< uInt > &indexVector, uInt nrrec, int options=DefaultSort, Bool tryGenSort=True) const |
| Sort the data array of nrrec records. More...
|
|
uInt64 | sort (Vector< uInt64 > &indexVector, uInt64 nrrec, int options=DefaultSort, Bool tryGenSort=True) const |
|
uInt | unique (Vector< uInt > &uniqueVector, uInt nrrec) const |
| Get all unique records in a sorted array. More...
|
|
uInt | unique (Vector< uInt > &uniqueVector, const Vector< uInt > &indexVector) const |
|
uInt | unique (Vector< uInt > &uniqueVector, Vector< size_t > &changeKey, const Vector< uInt > &indexVector) const |
|
uInt64 | unique (Vector< uInt64 > &uniqueVector, uInt64 nrrec) const |
|
uInt64 | unique (Vector< uInt64 > &uniqueVector, const Vector< uInt64 > &indexVector) const |
|
uInt64 | unique (Vector< uInt64 > &uniqueVector, Vector< size_t > &changeKey, const Vector< uInt64 > &indexVector) const |
|
|
template<typename T > |
T | doSort (Vector< T > &indexVector, T nrrec, int options=DefaultSort, Bool tryGenSort=True) const |
|
template<typename T > |
T | doUnique (Vector< T > &uniqueVector, T nrrec) const |
|
template<typename T > |
T | doUnique (Vector< T > &uniqueVector, const Vector< T > &indexVector) const |
|
template<typename T > |
T | doUnique (Vector< T > &uniqueVector, Vector< size_t > &changeKey, const Vector< T > &indexVector) const |
|
void | copy (const Sort &that) |
| Copy that Sort object to this. More...
|
|
void | addKey (const void *data, DataType, uInt increment, int options) |
| Add a sort key giving a data type and stride or the sort key. More...
|
|
void | addKey (SortKey *) |
|
template<typename T > |
T | insSort (T nr, T *indices) const |
| Do an insertion sort, optionally skipping duplicates. More...
|
|
template<typename T > |
T | insSortNoDup (T nr, T *indices) const |
|
template<typename T > |
T | parSort (int nthr, T nrrec, T *inx) const |
| Do a merge sort, if possible in parallel using OpenMP. More...
|
|
template<typename T > |
void | merge (T *inx, T *tmp, T size, T *index, T nparts) const |
|
template<typename T > |
T | quickSort (T nr, T *indices) const |
| Do a quicksort, optionally skipping duplicates (qkSort is the actual quicksort function). More...
|
|
template<typename T > |
T | quickSortNoDup (T nr, T *indices) const |
|
template<typename T > |
void | qkSort (T nr, T *indices) const |
|
template<typename T > |
T | heapSort (T nr, T *indices) const |
| Do a heapsort, optionally skipping duplicates. More...
|
|
template<typename T > |
T | heapSortNoDup (T nr, T *indices) const |
|
template<typename T > |
void | siftDown (T low, T up, T *indices) const |
| Siftdown algorithm for heapsort. More...
|
|
template<typename T > |
int | compare (T index1, T index2) const |
| Compare 2 records based on the comparison functions. More...
|
|
template<typename T > |
int | compareChangeIdx (T i1, T i2, size_t &idxComp) const |
| As compare() but it also gives back the index of the first comparison function that didn't match. More...
|
|
template<typename T > |
void | swap (T index1, T index2, T *indices) const |
| Swap 2 indices. More...
|
|
Sort on one or more keys, ascending and/or descending.
Intended use:
Public interface
Review Status
- Reviewed By:
- Friso Olnon
- Date Reviewed:
- 1995/03/01
- Test programs:
- tSort, tSort_1
Synopsis
Sort
lets you sort data on one or more keys in a mix of Sort::ascending
and Sort::descending
order. Duplicates can be skipped by giving the option Sort::NoDuplicates
. Only in this case the number of output elements can be different from the number of input elements.
The unique
function offers another way of getting unique values.
Class Sort
does not sort the data themselves, but returns an index to them. This gives more flexibility and allows the sort to be stable; but it is slower.
Very fast sorting of the data themselves can be done with the functions in class GenSort. If sorting on a single key with a standard data type is done, Sort will use GenSortIndirect to speed up the sort.
Four sort algorithms are provided:
Sort::ParSort
- The parallel merge sort is the fastest if it can use multiple threads. For a single thread it has O(n*log(n)) behaviour, but is slower than quicksort. A drawback is that it needs an extra index array to do the merge.
Sort::InsSort
- Insertion sort has O(n*n) behaviour, thus is very slow for large arrays. However, it is the fastest method for small arrays (< 50 elements) and for arrays already (almost) in the right order.
Sort::QuickSort
- Care has been taken to solve the well-known quicksort problems like "array already in order" or "many equal elements". The behaviour is O(n*log(n)) in all the cases tested, even in degenerated cases where the SUN Solaris qsort algorithm is O(n*n).
Sort::HeapSort
- Heapsort has O(n*log(n)) behaviour. Its speed is lower than that of QuickSort, so QuickSort is the default algorithm.
The default is to use QuickSort for small arrays or if only a single thread can be used. Otherwise ParSort is the default.
All sort algorithms are stable, which means that the original order is kept when keys are equal.
The sort is a four step process:
-
Construct the
Sort
object.
-
Define the sort keys. The function
sortKey
must be called for each sort key (the most significant one first). The comparison object can be passed in directly, or a basic data type can be given. In the latter case the appropriate ObjCompare comparison object will be created.
-
Sort the data. The function
sort
returns an index array, which is allocated when needed.
-
Destruct the
Sort
object (usually done automatically) and delete the index array.
The data can be in a single array of structs, in separate arrays, or in a mix of those. Of course, all arrays must have the same length. The data can be passed to the Sort
constructor and/or to the sortKey
function. If passed to the Sort
constructor, the offset of the data item in the data array must be given to sortKey
.
Example
In the first example we sort the data contained in two "parallel" arrays, idata
and ddata
, both of length nrdata
.
sort.sortKey (idata, TpInt);
Vector<uInt> inx;
for (
uInt i=0; i<nrdata; i++) {
cout << idata[inx[i]] << " " << ddata[inx[i]] << endl;
}
uInt sort(Vector< uInt > &indexVector, uInt nrrec, int options=DefaultSort, Bool tryGenSort=True) const
Sort the data array of nrrec records.
Sort()
The default constructor can be used when the data is only passed in via function sortKey.
Now nr
contains the nr of records (=nrdata
) and inx
an array of (sorted) indices.
In the second example we sort the data stored in an array of structs on the double (ascending) and the string (descending). We can pass the data to the Sort
constructor, and the offsets of the struct elements to the sortKey
function.
struct Ts {
String as;
double ad;
}
Vector<uInt> inx;
sort.sortKey ((
char*)&tsarr[0].ad - (
char*)tsarr, TpDouble);
sort.sortKey ((
char*)&tsarr[0].as - (
char*)tsarr, TpString,
Note that the first argument in function sortKey
gives the offset of the variable in the struct.
Alternatively, and probably slightly easier, we could pass the data to the sortKey
function and use an increment:
struct Ts {
String as;
double ad;
}
Vector<uInt> inx;
sort.sortKey (&tsarr[0].ad, TpDouble,
sizeof(Ts));
Finally, we could provide a comparison object for the struct.
struct Ts {
String as;
double ad;
}
class MyCompare: public BaseCompare {
virtual int comp (const void* val1, const void* val2) const
{
const Ts& t1 = *(Ts*)val1;
const Ts& t2 = *(Ts*)val2;
if (t1.ad < t2.ad) return -1;
if (t1.ad > t2.ad) return 1;
if (t1.as < t2.as) return 1;
if (t1.as > t2.as) return -1;
return 0;
}
};
Vector<uInt> inx;
sort.sortKey (tsarr, compareTs,
sizeof(Ts));
Definition at line 247 of file Sort.h.