FixArray.tlh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /***************************************************************************
  2. * E-Com Technology Ltd.
  3. *
  4. * ECOMPACS DICOM Network Transport Libraries * Version 0.1 Beta
  5. ***************************************************************************/
  6. #pragma warning (disable : 4800)
  7. // avoid bool (LastAccess);
  8. //////////////////////////////////////////////////////////////////////
  9. // Fixed, Fast-Access Array.
  10. //////////////////////////////////////////////////////////////////////
  11. template < class DATATYPE > class FixArray
  12. {
  13. protected:
  14. mutable int Top;
  15. int ArraySize;
  16. DATATYPE * DataTable;
  17. public:
  18. bool bAutoEnlarge;
  19. public:
  20. inline FixArray ()
  21. {
  22. ArraySize = 0;
  23. Top = 0;
  24. DataTable = NULL;
  25. bAutoEnlarge = false;
  26. }
  27. inline FixArray (UINT32 Size)
  28. {
  29. ArraySize = Size;
  30. Top = 0;
  31. DataTable = new DATATYPE [ ArraySize ];
  32. bAutoEnlarge = false;
  33. }
  34. ~FixArray () { Reset ();}
  35. inline int GetTop () const { return ( Top ); }
  36. inline int GetCapacity () const { return ( ArraySize ); }
  37. inline int GetSize () const { return ( ArraySize ); }
  38. inline void RemoveAll (void)
  39. {
  40. if ( DataTable) delete [] DataTable;
  41. DataTable = NULL;
  42. ArraySize = 0;
  43. Top = 0;
  44. }
  45. inline void Reset (void)
  46. {
  47. RemoveAll ();
  48. }
  49. inline bool IsEmpty (void) const
  50. {
  51. return (Top == 0);
  52. }
  53. inline void Empty (void)
  54. {
  55. Top = 0;
  56. }
  57. inline DATATYPE & operator [] (int Index) const
  58. {
  59. return (GetAt (Index));
  60. }
  61. inline DATATYPE & GetAt (int Index) const
  62. {
  63. if (Top <= Index)
  64. Top = Index + 1;
  65. if (Top > ArraySize)
  66. {
  67. DATATYPE * nul = NULL;
  68. return (*nul);
  69. }
  70. return (DataTable[Index]);
  71. }
  72. inline void MemorySet (const DATATYPE & toData)
  73. {
  74. for (int Index=0; Index<ArraySize; Index++)
  75. DataTable[Index] = toData;
  76. }
  77. inline int Add (const DATATYPE & Data)
  78. {
  79. if (Top >= ArraySize)
  80. {
  81. if (bAutoEnlarge)
  82. Enlarge (GetCapacity () + 1);
  83. }
  84. if (Top < ArraySize)
  85. {
  86. if (DataTable)
  87. DataTable [ Top ] = Data;
  88. ++Top;
  89. }
  90. else
  91. {
  92. throw ("Out of FixArray range in Add");
  93. return -1;
  94. }
  95. return Top;
  96. }
  97. /*
  98. inline void RemoveAt (int nPos)
  99. {
  100. #pragma message ("------------------------------------------")
  101. #pragma message ("Call FixArray::RemoveAt is NOT recommended")
  102. #pragma message ("------------------------------------------")
  103. if (nPos >= ArraySize)
  104. return;
  105. if (nPos < 0)
  106. return;
  107. for (int Index=nPos; Index<ArraySize-1; Index++)
  108. {
  109. DataTable[Index] = DataTable[Index+1];
  110. }
  111. Top --;
  112. }
  113. */
  114. inline void SetCapacity (int NewSize)
  115. {
  116. Enlarge (NewSize);
  117. }
  118. inline int Enlarge (int NewSize)
  119. {
  120. if (NewSize <= ArraySize)
  121. {
  122. return ArraySize;
  123. }
  124. DATATYPE * oldDataTable = DataTable;
  125. DataTable = new DATATYPE [NewSize];
  126. if (oldDataTable)
  127. {
  128. for (int Index=0; Index<Top; Index++)
  129. {
  130. DataTable[Index] = oldDataTable[Index];
  131. }
  132. }
  133. ArraySize = NewSize;
  134. if (oldDataTable) delete [] oldDataTable;
  135. return NewSize;
  136. }
  137. inline BOOL CopyTo (FixArray <DATATYPE> & array) const
  138. {
  139. array.SetCapacity (GetCapacity ());
  140. for (int Index = 0; Index<GetSize (); Index++)
  141. {
  142. array.DataTable[Index] = DataTable[Index];
  143. }
  144. array.Top = Top;
  145. return true;
  146. }
  147. inline BOOL CopyTo (Array <DATATYPE> & array) const
  148. {
  149. for (int Index = 0; Index<GetSize (); Index++)
  150. {
  151. array.Add (DataTable[Index]);
  152. }
  153. return true;
  154. }
  155. inline int Append (const FixArray <DATATYPE> & from)
  156. {
  157. Enlarge (this->GetTop () + from.GetTop ());
  158. for (int Index=0; Index<from.GetTop (); Index++)
  159. {
  160. DATATYPE dt = from[Index];
  161. Add (dt);
  162. }
  163. return GetTop ();
  164. }
  165. inline int Append (const Array <DATATYPE> & from)
  166. {
  167. Enlarge (this->GetTop () + from.GetTop ());
  168. for (Array <DATATYPE>::Iterator Iter (from); Iter; Iter++)
  169. while (Iter)
  170. {
  171. DATATYPE value = Iter ();
  172. Add (value);
  173. }
  174. return GetTop ();
  175. }
  176. inline void Swap (int ia, int ib)
  177. {
  178. DATATYPE & a = GetAt (ia);
  179. DATATYPE & b = GetAt (ib);
  180. DATATYPE v;
  181. v = a;
  182. a = b;
  183. b = v;
  184. }
  185. void Sort (void)
  186. {
  187. if (Top == 0)
  188. return;
  189. Sort (0, Top - 1);
  190. }
  191. template <class ODT> void Sort (Array <ODT> & ar)
  192. {
  193. if (Top == 0)
  194. return;
  195. return Sort (0, Top - 1, ar);
  196. }
  197. template <class ODT> void Sort (FixArray <ODT> & ar)
  198. {
  199. if (Top == 0)
  200. return;
  201. return Sort (0, Top - 1, ar);
  202. }
  203. inline void HeapSort ()
  204. {
  205. HeapSort (ArraySize - 1);
  206. }
  207. inline bool IsExist (const DATATYPE & Value) const
  208. {
  209. return IndexOf (Value) != -1;
  210. }
  211. inline int IndexOf (const DATATYPE & Data) const
  212. {
  213. for (int Index=0; Index<Top; Index++)
  214. {
  215. if (Data == DataTable[Index])
  216. return Index;
  217. }
  218. return -1;
  219. }
  220. template <class ODT> inline int IndexOf (const ODT & Key) const
  221. {
  222. for (int Index=0; Index<Top; Index++)
  223. {
  224. if (Key == DataTable[Index])
  225. return Index;
  226. }
  227. return -1;
  228. }
  229. template <class Compare> inline int IndexOf (const DATATYPE & Key, Compare cf) const
  230. {
  231. for (int Index=0; Index<Top; Index++)
  232. {
  233. if (cf (Key, DataTable[Index]) == 0)
  234. return Index;
  235. }
  236. return -1;
  237. }
  238. template <class ODT, class Compare> inline int IndexOf (const ODT & Key, Compare cf) const
  239. {
  240. for (int Index=0; Index<Top; Index++)
  241. {
  242. if (cf (Key, DataTable[Index]) == 0)
  243. return Index;
  244. }
  245. return -1;
  246. }
  247. inline int LastIndexOf (const DATATYPE & Data) const
  248. {
  249. for (int Index=Top-1; Index>=0; Index--)
  250. {
  251. if (Data == DataTable[Index])
  252. return Index;
  253. }
  254. return -1;
  255. }
  256. inline int IndexOfSorted (const DATATYPE & Data) const
  257. {
  258. int Low = 0;
  259. int High = Top - 1;
  260. while (Low <= High)
  261. {
  262. int Mid = (Low + High) >> 1;
  263. if (Data == DataTable[Mid]) return Mid;
  264. if (Data < DataTable[Mid]) High = Mid -1;
  265. else Low = Mid + 1;
  266. }
  267. return -1;
  268. }
  269. template <class ODT> inline int IndexOfSorted (const ODT & Key) const
  270. {
  271. int Low = 0;
  272. int High = Top - 1;
  273. while (Low <= High)
  274. {
  275. int Mid = (Low + High) >> 1;
  276. if (Key == DataTable[Mid]) return Mid;
  277. if (Key < DataTable[Mid]) High = Mid -1;
  278. else Low = Mid + 1;
  279. }
  280. return -1;
  281. }
  282. template <class Compare> inline int IndexOfSorted (const DATATYPE & Key, Compare cf) const
  283. {
  284. int Low = 0;
  285. int High = Top - 1;
  286. while (Low <= High)
  287. {
  288. int Mid = (Low + High) >> 1;
  289. if (cf (Key, DataTable[Mid]) == 0) return Mid;
  290. if (cf (Key, DataTable[Mid]) < 0) High = Mid -1;
  291. else Low = Mid + 1;
  292. }
  293. return -1;
  294. }
  295. template <class ODT, class Compare> inline int IndexOfSorted (const ODT & Key, Compare cf) const
  296. {
  297. int Low = 0;
  298. int High = Top - 1;
  299. while (Low <= High)
  300. {
  301. int Mid = (Low + High) >> 1;
  302. if (cf (Key, DataTable[Mid]) == 0) return Mid;
  303. if (cf (Key, DataTable[Mid]) < 0) High = Mid -1;
  304. else Low = Mid + 1;
  305. }
  306. return -1;
  307. }
  308. inline DATATYPE * Find (const DATATYPE & Key) const
  309. {
  310. int Index = IndexOf (Key);
  311. if (Index != -1)
  312. return &GetAt (Index);
  313. return NULL;
  314. }
  315. template <class ODT> inline DATATYPE * Find (const ODT & Key) const
  316. {
  317. int Index = IndexOf (Key);
  318. if (Index != -1)
  319. return &GetAt (Index);
  320. return NULL;
  321. }
  322. template <class Compare> inline DATATYPE * Find (const DATATYPE & Key, Compare cf) const
  323. {
  324. int Index = IndexOf (Key);
  325. if (Index != -1)
  326. return &GetAt (Index);
  327. return NULL;
  328. }
  329. inline DATATYPE * FindSorted (const DATATYPE & Key) const
  330. {
  331. int Index = IndexOfSorted (Key);
  332. if (Index != -1)
  333. return &GetAt (Index);
  334. return NULL;
  335. }
  336. template <class ODT> inline DATATYPE * FindSorted (const ODT & Key) const
  337. {
  338. int Index = IndexOfSorted (Key);
  339. if (Index != -1)
  340. return &GetAt (Index);
  341. return NULL;
  342. }
  343. template <class Compare> inline DATATYPE * FindSorted (const DATATYPE & Key, Compare cf) const
  344. {
  345. int Index = IndexOfSorted (Key, cf);
  346. if (Index != -1)
  347. return &GetAt (Index);
  348. return NULL;
  349. }
  350. template <class ODT, class Compare> inline DATATYPE * FindSorted (const ODT & Key, Compare cf) const
  351. {
  352. int Index = IndexOfSorted (Key, cf);
  353. if (Index != -1)
  354. return &GetAt (Index);
  355. return NULL;
  356. }
  357. template <class pfnForEach> void ForEach (pfnForEach pf)
  358. {
  359. for (int Index=0; Index<Top; Index++)
  360. {
  361. DATATYPE & dt = GetAt (Index);
  362. if (! pf (dt))
  363. break;
  364. }
  365. }
  366. template <class pfnForEach> void ForEach (pfnForEach pf) const
  367. {
  368. for (int Index=0; Index<Top; Index++)
  369. {
  370. const DATATYPE & dt = GetAt (Index);
  371. if (! pf (dt))
  372. break;
  373. }
  374. }
  375. protected:
  376. void Sort (int low, int high)
  377. {
  378. if (high <= low)
  379. return;
  380. if (high - low == 1)
  381. {
  382. if (GetAt (high) < GetAt (low))
  383. Swap (low, high);
  384. return;
  385. }
  386. // 存放中心索引及其值的局部变量及用于扫描的索引
  387. DATATYPE pivot;
  388. int scanUp, scanDown;
  389. int mid;
  390. mid = (low + high) / 2;
  391. pivot = GetAt (mid);
  392. Swap (mid, low);
  393. scanUp = low + 1; scanDown = high;
  394. do
  395. {
  396. while (scanUp <= scanDown && (*this)[scanUp] <= pivot)
  397. {
  398. scanUp ++;
  399. }
  400. while (pivot < (*this)[scanDown])
  401. {
  402. scanDown --;
  403. }
  404. if (scanUp < scanDown)
  405. {
  406. Swap (scanUp, scanDown);
  407. }
  408. }
  409. while (scanUp < scanDown);
  410. (*this)[low] = (*this)[scanDown];
  411. (*this)[scanDown] = pivot;
  412. if (low < scanDown - 1)
  413. Sort (low, scanDown - 1);
  414. if (scanDown + 1 < high)
  415. Sort (scanDown + 1, high);
  416. }
  417. template <class ODT> void Sort (int low, int high, Array <ODT> & ar);
  418. template <class ODT> void Sort (int low, int high, FixArray <ODT> & ar);
  419. // template <class ODT> friend void Array <DATATYPE>::Sort (int low, int high, Array <ODT> & ar);
  420. // template <class ODT> friend void Array <DATATYPE>::Sort (int low, int high, FixArray <ODT> & ar);
  421. protected:
  422. void HeapSort (int n);
  423. void HeapAdjust (int s, int m);
  424. };
  425. template <class DATATYPE> template <class ODT> void FixArray <DATATYPE>::Sort (int low, int high, Array <ODT> & ar)
  426. {
  427. if (high - low <= 0)
  428. return;
  429. if (high - low == 1)
  430. {
  431. if (GetAt (high) < GetAt (low))
  432. {
  433. Swap (low, high);
  434. ar.Swap (low, high);
  435. }
  436. return;
  437. }
  438. // 存放中心索引及其值的局部变量及用于扫描的索引
  439. int scanUp, scanDown;
  440. int mid;
  441. mid = (low + high) / 2;
  442. DATATYPE pivot = GetAt (mid);
  443. ODT __fvalue;
  444. __fvalue = ar.GetAt (mid);
  445. Swap (mid, low);
  446. ar.Swap (mid, low);
  447. scanUp = low + 1; scanDown = high;
  448. do
  449. {
  450. while (scanUp <= scanDown && (*this)[scanUp] <= pivot)
  451. {
  452. scanUp ++;
  453. }
  454. while (pivot < (*this)[scanDown])
  455. {
  456. scanDown --;
  457. }
  458. if (scanUp < scanDown)
  459. {
  460. Swap (scanUp, scanDown);
  461. ar.Swap (scanUp, scanDown);
  462. }
  463. }
  464. while (scanUp < scanDown);
  465. (*this)[low] = (*this)[scanDown];
  466. (*this)[scanDown] = pivot;
  467. {
  468. ArrayItem < ODT > * fdl;
  469. fdl = ar.PtrOfItemAt (scanDown);
  470. ar[low] = fdl->Data;
  471. fdl->Data = __fvalue;
  472. }
  473. if (low < scanDown - 1)
  474. Sort (low, scanDown - 1, ar);
  475. if (scanDown + 1 < high)
  476. Sort (scanDown + 1, high, ar);
  477. }
  478. template <class DATATYPE> template <class ODT> void FixArray <DATATYPE>::Sort (int low, int high, FixArray <ODT> & ar)
  479. {
  480. if (high - low <= 0)
  481. return;
  482. if (high - low == 1)
  483. {
  484. if (GetAt (high) < GetAt (low))
  485. {
  486. Swap (low, high);
  487. ar.Swap (low, high);
  488. }
  489. return;
  490. }
  491. // 存放中心索引及其值的局部变量及用于扫描的索引
  492. int scanUp, scanDown;
  493. int mid;
  494. mid = (low + high) / 2;
  495. DATATYPE pivot = GetAt (mid);
  496. ODT __fvalue;
  497. __fvalue = ar.GetAt (mid);
  498. Swap (mid, low);
  499. ar.Swap (mid, low);
  500. scanUp = low + 1; scanDown = high;
  501. do
  502. {
  503. while (scanUp <= scanDown && (*this)[scanUp] <= pivot)
  504. {
  505. scanUp ++;
  506. }
  507. while (pivot < (*this)[scanDown])
  508. {
  509. scanDown --;
  510. }
  511. if (scanUp < scanDown)
  512. {
  513. Swap (scanUp, scanDown);
  514. ar.Swap (scanUp, scanDown);
  515. }
  516. }
  517. while (scanUp < scanDown);
  518. (*this)[low] = (*this)[scanDown];
  519. (*this)[scanDown] = pivot;
  520. {
  521. ar[low] = ar[scanDown];
  522. ar[scanDown] = __fvalue;
  523. }
  524. if (low < scanDown - 1)
  525. Sort (low, scanDown - 1, ar);
  526. if (scanDown + 1 < high)
  527. Sort (scanDown + 1, high, ar);
  528. };
  529. template <class DATATYPE> void FixArray <DATATYPE>::HeapSort (int n)
  530. {
  531. for (int i=n/2; i>=0; --i)
  532. // 把R[1..n]建成大顶堆
  533. HeapAdjust (i, n);
  534. for (int i=n; i>=1; --i)
  535. {
  536. Swap (0, i);
  537. // 将堆顶记录和当前未经排序子序列
  538. // R[1..i]中最后一个记录相互交换
  539. HeapAdjust (0, i-1);
  540. // 将R[1..i-1] 重新调整为大顶堆
  541. }
  542. }
  543. template <class DATATYPE> void FixArray <DATATYPE>::HeapAdjust (int s, int m)
  544. {
  545. DATATYPE rc = GetAt (s);
  546. for (int j=2*s; j<=m; j*=2)
  547. {
  548. // 沿key较大的孩子结点向下筛选
  549. if (j < m && GetAt (j) < GetAt (j+1))
  550. j ++;
  551. // j为key较大的记录的下标
  552. if (rc >= GetAt (j))
  553. break;
  554. // rc应插入在位置s上
  555. Swap (s, j); s = j;
  556. }
  557. (*this)[s] = rc; // 插入
  558. }