C++
26 May 2010
 
 
 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#pragma inline
#include <asmrules.h>
#include <stdlib.h>
typedef int _CType comparF (const void _FAR *, const void _FAR *);
static comparF *Fcmp;
static unsigned qWidth;
static void near pascal Exchange (void *leftP, void *rightP)
{
#if 0
int i;
char c;
for (i = 0; i < qWidth; i++ ;)
{
c = *((char *) rightP);
*((char *) rightP )++ = *((char *) leftP);
*((char *) leftP )++ = c;
}
#endif
#if ! LDATA
asm push DS
#else
asm push DS
#endif
asm cld
asm mov cx, qWidth
asm LES_ di, rightP
asm LDS_ si, leftP
asm jnc xch_wordLoop
asm mov al, ES_ [di]
asm mov [si-1], al
xch_wordLoop:
asm mov ax, ES_ [di]
asm mov [si-2], ax
asm loop xch_wordLoop
xch_end:
#if LDATA
asm pop DS
#endif
return;
}
#ifdef __HUGE__
# define _LT_(x,y) (x < y)
#else
# define _LT_(x,y) ((unsigned short) x < (unsigned short) y)
#endif
#else
#define _LT_(x,y) (x < y)
#endif
#pragma warn -sig
#if defined(__HUGE__) || defined(__FARFUNCS__)
#pragma warn -sus
static void near pascal qSortHelp (char huge *pivotP, size_t nElem)
#else
static void near pascal qSortHelp (char *pivotP, size_t nElem)
#endif
{
#if defined(__HUGE__) || defined(__FARFUNCS__)
char huge *leftP, huge *rightP;
char huge *pivotEnd, huge *pivotTemp, huge *leftTemp;
#else
char *leftP, *rightP, *pivotEnd, *pivotTemp, *leftTemp;
#endif
unsigned lNum;
int retval;
tailRecursion:
if (nElem <= 2)
{
if (nElem == 2)
{
if (Fcmp (pivotP, rightP = qWidth + pivotP) > 0)
Exchange (pivotP, rightP);
}
return;
}
rightP = (nElem - 1) * qWidth + pivotP;
leftP = (nElem >> 1) * qWidth + pivotP;
if (Fcmp (leftP, rightP) > 0)
Exchange (leftP, rightP);
if (Fcmp (leftP, pivotP) > 0)
Exchange (leftP, pivotP);
else if (Fcmp (pivotP, rightP) > 0)
Exchange (pivotP, rightP);
if (nElem == 3)
{
Exchange (pivotP, leftP);
return;
}
leftP = pivotEnd = pivotP + qWidth;
do
{
while ((retval = Fcmp(leftP, pivotP)) <= 0)
{
if (retval == 0)
{
Exchange(leftP, pivotEnd);
pivotEnd += qWidth;
}
if (_LT_ (leftP, rightP))
leftP += qWidth;
else
goto qBreak;
}
while (_LT_(leftP, rightP))
{
if ((retval = Fcmp(pivotP, rightP)) < 0)
rightP -= qWidth;
else
{
Exchange (leftP, rightP);
if (retval != 0)
{
leftP += qWidth;
rightP -= qWidth;
}
break;
}
}
} while (_LT_(leftP, rightP));
qBreak:
if (Fcmp(leftP, pivotP) <= 0)
leftP = leftP + qWidth;
leftTemp = leftP - qWidth;
pivotTemp = pivotP;
while ((pivotTemp < pivotEnd) && (leftTemp >= pivotEnd))
{
Exchange(pivotTemp, leftTemp);
pivotTemp += qWidth;
leftTemp -= qWidth;
}
lNum = (leftP - pivotEnd) / qWidth;
nElem = ((nElem * qWidth + pivotP) - leftP)/qWidth;
// Sort smaller partition first to reduce stack usage
if (nElem < lNum)
{
qSortHelp (leftP, nElem);
nElem = lNum;
}
else
{
qSortHelp (pivotP, lNum);
pivotP = leftP;
}
goto tailRecursion;
}
#pragma warn .sig
#if defined(__HUGE__) || defined(__FARFUNCS__)
#pragma warn .sus
#endif
#if defined(__FARFUNCS__)
#include <_farfunc.h>
#endif
void _CType _FARFUNC qsort (void _FAR * baseP, size_t nElem, size_t width,
comparF *compar)
{
if ((qWidth = width) == 0)
return;
Fcmp = compar;
qSortHelp (baseP, nElem);
}