Sort.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. #define ELM(i ) data[i]
  6. #define COPY(dest, src) dest=src
  7. #define SWAP(a, b ) Swap(ELM(a), ELM(b))
  8. T1(TYPE) static INLINE void _Sort(TYPE *data, Int elms)
  9. {
  10. if(elms>1)
  11. {
  12. Memt<VecI2> stack; stack.New().set(0, elms-1);
  13. for(; stack.elms(); )
  14. {
  15. VecI2 lr=stack.pop();
  16. Int l =lr.x,
  17. r =lr.y;
  18. if(r-l>48) // 48 gave best results
  19. {
  20. // quicksort
  21. Int m=UInt(r+l)/2;
  22. if(ELM(l)>ELM(r))SWAP(l, r);
  23. if(ELM(l)>ELM(m))SWAP(l, m);
  24. if(ELM(m)>ELM(r))SWAP(m, r);
  25. Int i=l, j=r;
  26. TYPE temp=ELM(m);
  27. for(; i<=j; )
  28. {
  29. for(; ELM(i)<temp; )i++; // find first element from left that is larger or equal to 'temp'
  30. for(; ELM(j)>temp; )j--; // find first element from right that is smaller or equal to 'temp'
  31. if(i<=j)
  32. {
  33. SWAP(i, j);
  34. i++;
  35. j--;
  36. }
  37. }
  38. if(l<j)stack.New().set(l, j);
  39. if(i<r)stack.New().set(i, r);
  40. }else
  41. {
  42. // insertion sort
  43. for(Int i=l+1; i<=r; i++)
  44. {
  45. TYPE temp=ELM(i);
  46. #if 1 // faster
  47. Int j; for(j=i; j>l && ELM(j-1)>temp; j--)ELM(j)=ELM(j-1);
  48. COPY(ELM(j), temp);
  49. #else
  50. Int j; for(j=i; j>l && ELM(j-1)>temp; j--);
  51. _MoveElmLeftUnsafe(data, SIZE(TYPE), i, j, &temp);
  52. #endif
  53. }
  54. }
  55. }
  56. }
  57. }
  58. #undef SWAP
  59. #undef COPY
  60. #undef ELM
  61. void Sort(Int *data, Int elms) {_Sort(data, elms);}
  62. void Sort(Flt *data, Int elms) {_Sort(data, elms);}
  63. void Sort(Dbl *data, Int elms) {_Sort(data, elms);}
  64. /******************************************************************************/
  65. #define ELM(i ) (((Byte*)data)+(i)*elm_size)
  66. #define COPY(dest, src) CopyFast(dest, src, elm_size)
  67. #define SWAP(a, b ) SwapFast(ELM(a), ELM(b), elm_size)
  68. void _Sort(Ptr data, Int elms, Int elm_size, Int compare(CPtr a, CPtr b))
  69. {
  70. if(elms>1)
  71. {
  72. // init
  73. Memt<Byte > buf; buf.setNum(elm_size); Ptr temp=buf.data();
  74. Memt<VecI2> stack; stack.New().set(0, elms-1);
  75. for(; stack.elms(); )
  76. {
  77. VecI2 lr=stack.pop();
  78. Int l =lr.x,
  79. r =lr.y;
  80. if(r-l>16) // 16 gave the best result
  81. {
  82. // quicksort
  83. Int m=UInt(r+l)/2;
  84. if(compare(ELM(l), ELM(r))>0)SWAP(l, r);
  85. if(compare(ELM(l), ELM(m))>0)SWAP(l, m);
  86. if(compare(ELM(m), ELM(r))>0)SWAP(m, r);
  87. Int i=l, j=r;
  88. COPY(temp, ELM(m));
  89. for(; i<=j; )
  90. {
  91. for(; compare(ELM(i), temp)<0; )i++; // find first element from left that is larger or equal to 'temp'
  92. for(; compare(ELM(j), temp)>0; )j--; // find first element from right that is smaller or equal to 'temp'
  93. if(i<=j)
  94. {
  95. SWAP(i, j);
  96. i++;
  97. j--;
  98. }
  99. }
  100. if(l<j)stack.New().set(l, j);
  101. if(i<r)stack.New().set(i, r);
  102. }else
  103. {
  104. // insertion sort
  105. for(Int i=l+1; i<=r; i++)
  106. {
  107. #if 0 // slower
  108. COPY(temp, ELM(i));
  109. Int j; for(j=i; j>l && compare(ELM(j-1), temp)>0; j--)COPY(ELM(j), ELM(j-1));
  110. COPY(ELM(j), temp);
  111. #else
  112. CPtr test=ELM(i);
  113. Int j; for(j=i; j>l && compare(ELM(j-1), test)>0; j--);
  114. _MoveElmLeftUnsafe(data, elm_size, i, j, temp);
  115. #endif
  116. }
  117. }
  118. }
  119. }
  120. }
  121. #undef ELM
  122. #define ELM(i) memb[i]
  123. void _Sort(_Memb &memb, Int compare(CPtr a, CPtr b))
  124. {
  125. Int elm_size=memb.elmSize();
  126. if(memb.elms()>1)
  127. {
  128. // init
  129. Memt<Byte > buf; buf.setNum(elm_size); Ptr temp=buf.data();
  130. Memt<VecI2> stack; stack.New().set(0, memb.elms()-1);
  131. for(; stack.elms(); )
  132. {
  133. VecI2 lr=stack.pop();
  134. Int l =lr.x,
  135. r =lr.y;
  136. if(r-l>16) // 16 gave the best result
  137. {
  138. // quicksort
  139. Int m=UInt(r+l)/2;
  140. if(compare(ELM(l), ELM(r))>0)SWAP(l, r);
  141. if(compare(ELM(l), ELM(m))>0)SWAP(l, m);
  142. if(compare(ELM(m), ELM(r))>0)SWAP(m, r);
  143. Int i=l, j=r;
  144. COPY(temp, ELM(m));
  145. for(; i<=j; )
  146. {
  147. for(; compare(ELM(i), temp)<0; )i++; // find first element from left that is larger or equal to 'temp'
  148. for(; compare(ELM(j), temp)>0; )j--; // find first element from right that is smaller or equal to 'temp'
  149. if(i<=j)
  150. {
  151. SWAP(i, j);
  152. i++;
  153. j--;
  154. }
  155. }
  156. if(l<j)stack.New().set(l, j);
  157. if(i<r)stack.New().set(i, r);
  158. }else
  159. {
  160. // insertion sort
  161. for(Int i=l+1; i<=r; i++)
  162. {
  163. #if 0 // slower
  164. COPY(temp, ELM(i));
  165. Int j; for(j=i; j>l && compare(ELM(j-1), temp)>0; j--)COPY(ELM(j), ELM(j-1));
  166. COPY(ELM(j), temp);
  167. #else
  168. CPtr test=ELM(i);
  169. Int j; for(j=i; j>l && compare(ELM(j-1), test)>0; j--);
  170. memb.moveElmLeftUnsafe(i, j, temp);
  171. #endif
  172. }
  173. }
  174. }
  175. }
  176. }
  177. #undef COPY
  178. #undef ELM
  179. #define ELM(i ) memx[i]
  180. #undef SWAP
  181. #define SWAP(a, b) memx.swapOrder(a, b)
  182. void _Sort(_Memx &memx, Int compare(CPtr a, CPtr b))
  183. {
  184. if(memx.elms()>1)
  185. {
  186. Memt<VecI2> stack; stack.New().set(0, memx.elms()-1);
  187. for(; stack.elms(); )
  188. {
  189. VecI2 lr=stack.pop();
  190. Int l =lr.x,
  191. r =lr.y;
  192. if(r-l>16) // 16 gave the best result
  193. {
  194. // quicksort
  195. Int m=UInt(r+l)/2;
  196. if(compare(ELM(l), ELM(r))>0)SWAP(l, r);
  197. if(compare(ELM(l), ELM(m))>0)SWAP(l, m);
  198. if(compare(ELM(m), ELM(r))>0)SWAP(m, r);
  199. Int i=l, j=r;
  200. Ptr temp=ELM(m); // we can use this because address remains the same
  201. for(; i<=j; )
  202. {
  203. for(; compare(ELM(i), temp)<0; )i++; // find first element from left that is larger or equal to 'temp'
  204. for(; compare(ELM(j), temp)>0; )j--; // find first element from right that is smaller or equal to 'temp'
  205. if(i<=j)
  206. {
  207. SWAP(i, j);
  208. i++;
  209. j--;
  210. }
  211. }
  212. if(l<j)stack.New().set(l, j);
  213. if(i<r)stack.New().set(i, r);
  214. }else
  215. {
  216. // insertion sort
  217. for(Int i=l+1; i<=r; i++)
  218. {
  219. #if 0 // slower
  220. Ptr temp=ELM(i); // we can use this because address remains the same
  221. Int j; for(j=i; j>l && compare(ELM(j-1), temp)>0; j--)SWAP(j, j-1);
  222. #else
  223. CPtr test=ELM(i);
  224. Int j; for(j=i; j>l && compare(ELM(j-1), test)>0; j--);
  225. memx.moveElmLeftUnsafe(i, j);
  226. #endif
  227. }
  228. }
  229. }
  230. }
  231. }
  232. #undef ELM
  233. #define ELM(i ) meml[i]
  234. #undef SWAP
  235. #define SWAP(a, b) meml.swapOrder(a, b)
  236. void _Sort(_Meml &meml, Int compare(CPtr a, CPtr b)) // TODO: this is slow for Meml
  237. {
  238. if(meml.elms()>1)
  239. {
  240. Memt<VecI2> stack; stack.New().set(0, meml.elms()-1);
  241. for(; stack.elms(); )
  242. {
  243. VecI2 lr=stack.pop();
  244. Int l =lr.x,
  245. r =lr.y;
  246. if(r-l>16) // 16 gave the best result
  247. {
  248. // quicksort
  249. Int m=UInt(r+l)/2;
  250. if(compare(ELM(l), ELM(r))>0)SWAP(l, r);
  251. if(compare(ELM(l), ELM(m))>0)SWAP(l, m);
  252. if(compare(ELM(m), ELM(r))>0)SWAP(m, r);
  253. Int i=l, j=r;
  254. Ptr temp=ELM(m); // we can use this because address remains the same
  255. for(; i<=j; )
  256. {
  257. for(; compare(ELM(i), temp)<0; )i++; // find first element from left that is larger or equal to 'temp'
  258. for(; compare(ELM(j), temp)>0; )j--; // find first element from right that is smaller or equal to 'temp'
  259. if(i<=j)
  260. {
  261. SWAP(i, j);
  262. i++;
  263. j--;
  264. }
  265. }
  266. if(l<j)stack.New().set(l, j);
  267. if(i<r)stack.New().set(i, r);
  268. }else
  269. {
  270. // insertion sort
  271. for(Int i=l+1; i<=r; i++)
  272. {
  273. Ptr temp=ELM(i); // we can use this because address remains the same
  274. Int j; for(j=i; j>l && compare(ELM(j-1), temp)>0; j--)SWAP(j, j-1);
  275. }
  276. }
  277. }
  278. }
  279. }
  280. #undef SWAP
  281. #undef ELM
  282. /******************************************************************************/
  283. Bool _BinarySearch(CPtr data, Int elms, Int elm_size, CPtr value, Int &index, Int compare(CPtr a, CPtr b))
  284. {
  285. Int l=0, r=elms; for(; l<r; )
  286. {
  287. Int mid=UInt(l+r)/2,
  288. c =compare(((Byte*)data)+mid*elm_size, value);
  289. if( c<0)l=mid+1;else
  290. if( c>0)r=mid ;else {index=mid; return true;}
  291. }
  292. index=l; return false;
  293. }
  294. Bool _BinarySearch(C _Memb &data, CPtr value, Int &index, Int compare(CPtr a, CPtr b))
  295. {
  296. Int l=0, r=data.elms(); for(; l<r; )
  297. {
  298. Int mid=UInt(l+r)/2,
  299. c =compare(data[mid], value);
  300. if( c<0)l=mid+1;else
  301. if( c>0)r=mid ;else {index=mid; return true;}
  302. }
  303. index=l; return false;
  304. }
  305. Bool _BinarySearch(C _Memx &data, CPtr value, Int &index, Int compare(CPtr a, CPtr b))
  306. {
  307. Int l=0, r=data.elms(); for(; l<r; )
  308. {
  309. Int mid=UInt(l+r)/2,
  310. c =compare(data[mid], value);
  311. if( c<0)l=mid+1;else
  312. if( c>0)r=mid ;else {index=mid; return true;}
  313. }
  314. index=l; return false;
  315. }
  316. Bool _BinarySearch(C _Meml &data, CPtr value, Int &index, Int compare(CPtr a, CPtr b))
  317. {
  318. Int pos=0; MemlNode *node=data.first(); // get first node
  319. Int l=0, r=data.elms(); for(; l<r; )
  320. {
  321. Int mid=UInt(l+r)/2;
  322. for(; pos<mid; pos++)node=node->next(); // go forward
  323. for(; pos>mid; pos--)node=node->prev(); // go back
  324. Int c=compare(node->data(), value);
  325. if( c<0)l=mid+1;else
  326. if( c>0)r=mid ;else {index=mid; return true;}
  327. }
  328. index=l; return false;
  329. }
  330. /******************************************************************************/
  331. }
  332. /******************************************************************************/