A C language implementation without recursive efficient fast sort algorithm

xiaoxiao2021-03-06  63

Recently preparing a program that is high in performance requirements, to use the sort function. There are many types of data to be sorted, with integer, floating point, and various structures (compared to a certain attribute). If the libc's QSort () function is called, the overhead of calling the comparison function will be large. Therefore, you will have an idea that you write a sorting function. Due to the diversity of data types, the algorithm must have a genericity. But I don't want to use the cost of calling the comparison function, so I can only be implemented with macro. Since rapid sorting is the current fastest gear sort algorithm, the current sequencing algorithm is currently selected. I chose the three-way division of Bentley-MCILROY, the prototype is as follows:

Void Quicksort (item a [], int L, int R)

{

INT i = L-1, J = R, P = L-1, Q = R; Item V = a [R];

IF (r <= l) return;

For (;;) {

While (a [ i]

While (V

IF (i> = j) Break;

Exch (a [i], a [j]);

IF (a [i] == v) {p ; Exch (a [p], a [i]);}

IF (v == a [j]) {q-; exch (a [j], a [q]);}

}

Exch (a [i], a [r]); j = i-1; i = i 1;

For (k = L; k

For (k = r-1; k> q; k - i ) Exch (a [i], a [k]);

Quicksort (A, L, J);

Quicksort (A, I, R);

} But rapid sorting is sorted by grasping method, so there is a recursive call of functions. This brings difficulties to the use of macro. There is no way, you have to simulate it with a stack. However, the stack is likely to overflow, or use libc's QSort () to sort the unsorted part of data when overflowing, but in cases it is not used. The final decision algorithm is as follows (where the amount of insertion is used in the amount of data is the content of me to increase):

#define libcswap (x, y, t) (t) = (x); (x) = (y); (y) = (t)

#define libcsimplelt (x, y) ((x) <(y))

#define libcsimpleeq (x, y) ((x) == (y))

EXTERN INT LIBCINTCMP (Const Void * X, Const Void * Y);

#define libcquicksort (Type, PDAT, NCNT, PLTFUNC, PEQFUNC, PCMPFUNC) /

DO {/

INT Stack [1024], TOP = 1, L, R, K, I, J, P, Q; /

Type v, t; /

/ * STACK Save the stop point to sort the data * /

Stack [0] = 0; /

Stack [1] = (NCNT) - 1; /

While (TOP> = 0) {/

R = stack [top -]; l = stack [top--]; /

/ * Opened from the stack to sort the data range, namely data between [L, R] * /

i = L - 1; j = r; p = i; q = r; /

v = (pdat) [R]; // * Sort in insertion sorting * /

IF (r <= l 31) /

CONTINUE; /

For (;;) {/

While (PLTFUNC ((PDAT) [ i], V)); /

While (PLTFUNC (V, (PDAT) [- j])) IF (j == L) Break; /

IF (i> = j) BREAK; /

Libcswap (PDAT) [I], (PDAT) [J], T); /

IF (PEQFunc (PDAT) (PDAT) {P ; libcswap ((pdat) [p], (pdat) [i], t);} /

IF (PEQFunc (V, (PDAT) [J])) {Q-; libcswap ((pdat) [j], (pdat) [q], t);} /

} /

Libcswap (PDAT) [I], (PDAT) [R], T); /

J = I - 1; i ; /

For (k = L; k

For (k = r - 1; k> q; k -, i ) {libcswap ((pdat) [i], (pdat) [k], t);} /

IF (TOP <1019) {/

/ * Equivalent to recursive call qsort (pdat, l, j) * /

Stack [ TOP] = L; Stack [ TOP] = J; /

/ * Equivalent to recursive call qsort (pdat, i, r) * /

Stack [ TOP] = I; Stack [ TOP] = R; /

} /

Else {/

/ * Stack overflow, call libc Qsort () * /

Qsort (PDAT), J - L 1, SizeOf (Type), PCMPFUNC); /

QSort (PDAT) I, R - I 1, SizeOf (Type), PCMPFUNC); /

} /

} /

/ * Insert sort * /

For (i = 1; i

T = (pdat) [i]; /

For (j = i; j> 0 && pltfunc (t, pdat) [j - 1]); J-) /

(PDAT) [J] = (PDAT) [J - 1]; /

(PDAT) [J] = T; /

} /

} while (0);

This way, use:

Libcquicksort (INT, PDAT, NCNT, LIBCSIMPLELT, LIBCSIMPLEEQ, LIBCINTCMP); sorting of an array of integer arrays can be completed. On my machine, the function sorted the efficiency of the integer data is about 2.5 times the QSort () in libc.


New Post(0)