Tree.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /*******************************************************************************
  2. * Copyright (c) 2009, 2018 IBM Corp.
  3. *
  4. * All rights reserved. This program and the accompanying materials
  5. * are made available under the terms of the Eclipse Public License v1.0
  6. * and Eclipse Distribution License v1.0 which accompany this distribution.
  7. *
  8. * The Eclipse Public License is available at
  9. * http://www.eclipse.org/legal/epl-v10.html
  10. * and the Eclipse Distribution License is available at
  11. * http://www.eclipse.org/org/documents/edl-v10.php.
  12. *
  13. * Contributors:
  14. * Ian Craggs - initial implementation and documentation
  15. *******************************************************************************/
  16. /** @file
  17. * \brief functions which apply to tree structures.
  18. *
  19. * These trees can hold data of any sort, pointed to by the content pointer of the
  20. * Node structure.
  21. * */
  22. #define NO_HEAP_TRACKING 1
  23. #include "Tree.h"
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include "Heap.h"
  28. int isRed(Node* aNode);
  29. int isBlack(Node* aNode);
  30. /*int TreeWalk(Node* curnode, int depth);*/
  31. /*int TreeMaxDepth(Tree *aTree);*/
  32. void TreeRotate(Tree* aTree, Node* curnode, int direction, int index);
  33. Node* TreeBAASub(Tree* aTree, Node* curnode, int which, int index);
  34. void TreeBalanceAfterAdd(Tree* aTree, Node* curnode, int index);
  35. void* TreeAddByIndex(Tree* aTree, void* content, size_t size, int index);
  36. Node* TreeFindIndex1(Tree* aTree, void* key, int index, int value);
  37. Node* TreeFindContentIndex(Tree* aTree, void* key, int index);
  38. Node* TreeMinimum(Node* curnode);
  39. Node* TreeSuccessor(Node* curnode);
  40. Node* TreeNextElementIndex(Tree* aTree, Node* curnode, int index);
  41. Node* TreeBARSub(Tree* aTree, Node* curnode, int which, int index);
  42. void TreeBalanceAfterRemove(Tree* aTree, Node* curnode, int index);
  43. void* TreeRemoveIndex(Tree* aTree, void* content, int index);
  44. void TreeInitializeNoMalloc(Tree* aTree, int(*compare)(void*, void*, int))
  45. {
  46. memset(aTree, '\0', sizeof(Tree));
  47. aTree->heap_tracking = 1;
  48. aTree->index[0].compare = compare;
  49. aTree->indexes = 1;
  50. }
  51. /**
  52. * Allocates and initializes a new tree structure.
  53. * @return a pointer to the new tree structure
  54. */
  55. Tree* TreeInitialize(int(*compare)(void*, void*, int))
  56. {
  57. #if defined(UNIT_TESTS)
  58. Tree* newt = malloc(sizeof(Tree));
  59. #else
  60. Tree* newt = mymalloc(__FILE__, __LINE__, sizeof(Tree));
  61. #endif
  62. TreeInitializeNoMalloc(newt, compare);
  63. return newt;
  64. }
  65. void TreeAddIndex(Tree* aTree, int(*compare)(void*, void*, int))
  66. {
  67. aTree->index[aTree->indexes].compare = compare;
  68. ++(aTree->indexes);
  69. }
  70. void TreeFree(Tree* aTree)
  71. {
  72. #if defined(UNIT_TESTS)
  73. free(aTree);
  74. #else
  75. (aTree->heap_tracking) ? myfree(__FILE__, __LINE__, aTree) : free(aTree);
  76. #endif
  77. }
  78. #define LEFT 0
  79. #define RIGHT 1
  80. #if !defined(max)
  81. #define max(a, b) (a > b) ? a : b;
  82. #endif
  83. int isRed(Node* aNode)
  84. {
  85. return (aNode != NULL) && (aNode->red);
  86. }
  87. int isBlack(Node* aNode)
  88. {
  89. return (aNode == NULL) || (aNode->red == 0);
  90. }
  91. #if 0
  92. int TreeWalk(Node* curnode, int depth)
  93. {
  94. if (curnode)
  95. {
  96. int left = TreeWalk(curnode->child[LEFT], depth+1);
  97. int right = TreeWalk(curnode->child[RIGHT], depth+1);
  98. depth = max(left, right);
  99. if (curnode->red)
  100. {
  101. /*if (isRed(curnode->child[LEFT]) || isRed(curnode->child[RIGHT]))
  102. {
  103. printf("red/black tree violation %p\n", curnode->content);
  104. exit(-99);
  105. }*/;
  106. }
  107. }
  108. return depth;
  109. }
  110. int TreeMaxDepth(Tree *aTree)
  111. {
  112. int rc = TreeWalk(aTree->index[0].root, 0);
  113. /*if (aTree->root->red)
  114. {
  115. printf("root node should not be red %p\n", aTree->root->content);
  116. exit(-99);
  117. }*/
  118. return rc;
  119. }
  120. #endif
  121. void TreeRotate(Tree* aTree, Node* curnode, int direction, int index)
  122. {
  123. Node* other = curnode->child[!direction];
  124. curnode->child[!direction] = other->child[direction];
  125. if (other->child[direction] != NULL)
  126. other->child[direction]->parent = curnode;
  127. other->parent = curnode->parent;
  128. if (curnode->parent == NULL)
  129. aTree->index[index].root = other;
  130. else if (curnode == curnode->parent->child[direction])
  131. curnode->parent->child[direction] = other;
  132. else
  133. curnode->parent->child[!direction] = other;
  134. other->child[direction] = curnode;
  135. curnode->parent = other;
  136. }
  137. Node* TreeBAASub(Tree* aTree, Node* curnode, int which, int index)
  138. {
  139. Node* uncle = curnode->parent->parent->child[which];
  140. if (isRed(uncle))
  141. {
  142. curnode->parent->red = uncle->red = 0;
  143. curnode = curnode->parent->parent;
  144. curnode->red = 1;
  145. }
  146. else
  147. {
  148. if (curnode == curnode->parent->child[which])
  149. {
  150. curnode = curnode->parent;
  151. TreeRotate(aTree, curnode, !which, index);
  152. }
  153. curnode->parent->red = 0;
  154. curnode->parent->parent->red = 1;
  155. TreeRotate(aTree, curnode->parent->parent, which, index);
  156. }
  157. return curnode;
  158. }
  159. void TreeBalanceAfterAdd(Tree* aTree, Node* curnode, int index)
  160. {
  161. while (curnode && isRed(curnode->parent) && curnode->parent->parent)
  162. {
  163. if (curnode->parent == curnode->parent->parent->child[LEFT])
  164. curnode = TreeBAASub(aTree, curnode, RIGHT, index);
  165. else
  166. curnode = TreeBAASub(aTree, curnode, LEFT, index);
  167. }
  168. aTree->index[index].root->red = 0;
  169. }
  170. /**
  171. * Add an item to a tree
  172. * @param aTree the list to which the item is to be added
  173. * @param content the list item content itself
  174. * @param size the size of the element
  175. */
  176. void* TreeAddByIndex(Tree* aTree, void* content, size_t size, int index)
  177. {
  178. Node* curparent = NULL;
  179. Node* curnode = aTree->index[index].root;
  180. Node* newel = NULL;
  181. int left = 0;
  182. int result = 1;
  183. void* rc = NULL;
  184. while (curnode)
  185. {
  186. result = aTree->index[index].compare(curnode->content, content, 1);
  187. left = (result > 0);
  188. if (result == 0)
  189. break;
  190. else
  191. {
  192. curparent = curnode;
  193. curnode = curnode->child[left];
  194. }
  195. }
  196. if (result == 0)
  197. {
  198. if (aTree->allow_duplicates)
  199. goto exit; /* exit(-99); */
  200. else
  201. {
  202. newel = curnode;
  203. rc = newel->content;
  204. if (index == 0)
  205. aTree->size += (size - curnode->size);
  206. }
  207. }
  208. else
  209. {
  210. #if defined(UNIT_TESTS)
  211. newel = malloc(sizeof(Node));
  212. #else
  213. newel = (aTree->heap_tracking) ? mymalloc(__FILE__, __LINE__, sizeof(Node)) : malloc(sizeof(Node));
  214. #endif
  215. memset(newel, '\0', sizeof(Node));
  216. if (curparent)
  217. curparent->child[left] = newel;
  218. else
  219. aTree->index[index].root = newel;
  220. newel->parent = curparent;
  221. newel->red = 1;
  222. if (index == 0)
  223. {
  224. ++(aTree->count);
  225. aTree->size += size;
  226. }
  227. }
  228. newel->content = content;
  229. newel->size = size;
  230. TreeBalanceAfterAdd(aTree, newel, index);
  231. exit:
  232. return rc;
  233. }
  234. void* TreeAdd(Tree* aTree, void* content, size_t size)
  235. {
  236. void* rc = NULL;
  237. int i;
  238. for (i = 0; i < aTree->indexes; ++i)
  239. rc = TreeAddByIndex(aTree, content, size, i);
  240. return rc;
  241. }
  242. Node* TreeFindIndex1(Tree* aTree, void* key, int index, int value)
  243. {
  244. int result = 0;
  245. Node* curnode = aTree->index[index].root;
  246. while (curnode)
  247. {
  248. result = aTree->index[index].compare(curnode->content, key, value);
  249. if (result == 0)
  250. break;
  251. else
  252. curnode = curnode->child[result > 0];
  253. }
  254. return curnode;
  255. }
  256. Node* TreeFindIndex(Tree* aTree, void* key, int index)
  257. {
  258. return TreeFindIndex1(aTree, key, index, 0);
  259. }
  260. Node* TreeFindContentIndex(Tree* aTree, void* key, int index)
  261. {
  262. return TreeFindIndex1(aTree, key, index, 1);
  263. }
  264. Node* TreeFind(Tree* aTree, void* key)
  265. {
  266. return TreeFindIndex(aTree, key, 0);
  267. }
  268. Node* TreeMinimum(Node* curnode)
  269. {
  270. if (curnode)
  271. while (curnode->child[LEFT])
  272. curnode = curnode->child[LEFT];
  273. return curnode;
  274. }
  275. Node* TreeSuccessor(Node* curnode)
  276. {
  277. if (curnode->child[RIGHT])
  278. curnode = TreeMinimum(curnode->child[RIGHT]);
  279. else
  280. {
  281. Node* curparent = curnode->parent;
  282. while (curparent && curnode == curparent->child[RIGHT])
  283. {
  284. curnode = curparent;
  285. curparent = curparent->parent;
  286. }
  287. curnode = curparent;
  288. }
  289. return curnode;
  290. }
  291. Node* TreeNextElementIndex(Tree* aTree, Node* curnode, int index)
  292. {
  293. if (curnode == NULL)
  294. curnode = TreeMinimum(aTree->index[index].root);
  295. else
  296. curnode = TreeSuccessor(curnode);
  297. return curnode;
  298. }
  299. Node* TreeNextElement(Tree* aTree, Node* curnode)
  300. {
  301. return TreeNextElementIndex(aTree, curnode, 0);
  302. }
  303. Node* TreeBARSub(Tree* aTree, Node* curnode, int which, int index)
  304. {
  305. Node* sibling = curnode->parent->child[which];
  306. if (isRed(sibling))
  307. {
  308. sibling->red = 0;
  309. curnode->parent->red = 1;
  310. TreeRotate(aTree, curnode->parent, !which, index);
  311. sibling = curnode->parent->child[which];
  312. }
  313. if (!sibling)
  314. curnode = curnode->parent;
  315. else if (isBlack(sibling->child[!which]) && isBlack(sibling->child[which]))
  316. {
  317. sibling->red = 1;
  318. curnode = curnode->parent;
  319. }
  320. else
  321. {
  322. if (isBlack(sibling->child[which]))
  323. {
  324. sibling->child[!which]->red = 0;
  325. sibling->red = 1;
  326. TreeRotate(aTree, sibling, which, index);
  327. sibling = curnode->parent->child[which];
  328. }
  329. sibling->red = curnode->parent->red;
  330. curnode->parent->red = 0;
  331. sibling->child[which]->red = 0;
  332. TreeRotate(aTree, curnode->parent, !which, index);
  333. curnode = aTree->index[index].root;
  334. }
  335. return curnode;
  336. }
  337. void TreeBalanceAfterRemove(Tree* aTree, Node* curnode, int index)
  338. {
  339. while (curnode != aTree->index[index].root && isBlack(curnode))
  340. {
  341. /* curnode->content == NULL must equal curnode == NULL */
  342. if (((curnode->content) ? curnode : NULL) == curnode->parent->child[LEFT])
  343. curnode = TreeBARSub(aTree, curnode, RIGHT, index);
  344. else
  345. curnode = TreeBARSub(aTree, curnode, LEFT, index);
  346. }
  347. curnode->red = 0;
  348. }
  349. /**
  350. * Remove an item from a tree
  351. * @param aTree the list to which the item is to be added
  352. * @param curnode the list item content itself
  353. */
  354. void* TreeRemoveNodeIndex(Tree* aTree, Node* curnode, int index)
  355. {
  356. Node* redundant = curnode;
  357. Node* curchild = NULL;
  358. size_t size = curnode->size;
  359. void* content = curnode->content;
  360. /* if the node to remove has 0 or 1 children, it can be removed without involving another node */
  361. if (curnode->child[LEFT] && curnode->child[RIGHT]) /* 2 children */
  362. redundant = TreeSuccessor(curnode); /* now redundant must have at most one child */
  363. curchild = redundant->child[(redundant->child[LEFT] != NULL) ? LEFT : RIGHT];
  364. if (curchild) /* we could have no children at all */
  365. curchild->parent = redundant->parent;
  366. if (redundant->parent == NULL)
  367. aTree->index[index].root = curchild;
  368. else
  369. {
  370. if (redundant == redundant->parent->child[LEFT])
  371. redundant->parent->child[LEFT] = curchild;
  372. else
  373. redundant->parent->child[RIGHT] = curchild;
  374. }
  375. if (redundant != curnode)
  376. {
  377. curnode->content = redundant->content;
  378. curnode->size = redundant->size;
  379. }
  380. if (isBlack(redundant))
  381. {
  382. if (curchild == NULL)
  383. {
  384. if (redundant->parent)
  385. {
  386. Node temp;
  387. memset(&temp, '\0', sizeof(Node));
  388. temp.parent = redundant->parent;
  389. temp.red = 0;
  390. TreeBalanceAfterRemove(aTree, &temp, index);
  391. }
  392. }
  393. else
  394. TreeBalanceAfterRemove(aTree, curchild, index);
  395. }
  396. #if defined(UNIT_TESTS)
  397. free(redundant);
  398. #else
  399. (aTree->heap_tracking) ? myfree(__FILE__, __LINE__, redundant) : free(redundant);
  400. #endif
  401. if (index == 0)
  402. {
  403. aTree->size -= size;
  404. --(aTree->count);
  405. }
  406. return content;
  407. }
  408. /**
  409. * Remove an item from a tree
  410. * @param aTree the list to which the item is to be added
  411. * @param curnode the list item content itself
  412. */
  413. void* TreeRemoveIndex(Tree* aTree, void* content, int index)
  414. {
  415. Node* curnode = TreeFindContentIndex(aTree, content, index);
  416. if (curnode == NULL)
  417. return NULL;
  418. return TreeRemoveNodeIndex(aTree, curnode, index);
  419. }
  420. void* TreeRemove(Tree* aTree, void* content)
  421. {
  422. int i;
  423. void* rc = NULL;
  424. for (i = 0; i < aTree->indexes; ++i)
  425. rc = TreeRemoveIndex(aTree, content, i);
  426. return rc;
  427. }
  428. void* TreeRemoveKeyIndex(Tree* aTree, void* key, int index)
  429. {
  430. Node* curnode = TreeFindIndex(aTree, key, index);
  431. void* content = NULL;
  432. int i;
  433. if (curnode == NULL)
  434. return NULL;
  435. content = TreeRemoveNodeIndex(aTree, curnode, index);
  436. for (i = 0; i < aTree->indexes; ++i)
  437. {
  438. if (i != index)
  439. content = TreeRemoveIndex(aTree, content, i);
  440. }
  441. return content;
  442. }
  443. void* TreeRemoveKey(Tree* aTree, void* key)
  444. {
  445. return TreeRemoveKeyIndex(aTree, key, 0);
  446. }
  447. int TreeIntCompare(void* a, void* b, int content)
  448. {
  449. int i = *((int*)a);
  450. int j = *((int*)b);
  451. /* printf("comparing %d %d\n", *((int*)a), *((int*)b)); */
  452. return (i > j) ? -1 : (i == j) ? 0 : 1;
  453. }
  454. int TreePtrCompare(void* a, void* b, int content)
  455. {
  456. return (a > b) ? -1 : (a == b) ? 0 : 1;
  457. }
  458. int TreeStringCompare(void* a, void* b, int content)
  459. {
  460. return strcmp((char*)a, (char*)b);
  461. }
  462. #if defined(UNIT_TESTS)
  463. int check(Tree *t)
  464. {
  465. Node* curnode = NULL;
  466. int rc = 0;
  467. curnode = TreeNextElement(t, curnode);
  468. while (curnode)
  469. {
  470. Node* prevnode = curnode;
  471. curnode = TreeNextElement(t, curnode);
  472. if (prevnode && curnode && (*(int*)(curnode->content) < *(int*)(prevnode->content)))
  473. {
  474. printf("out of order %d < %d\n", *(int*)(curnode->content), *(int*)(prevnode->content));
  475. rc = 99;
  476. }
  477. }
  478. return rc;
  479. }
  480. int traverse(Tree *t, int lookfor)
  481. {
  482. Node* curnode = NULL;
  483. int rc = 0;
  484. printf("Traversing\n");
  485. curnode = TreeNextElement(t, curnode);
  486. /* printf("content int %d\n", *(int*)(curnode->content)); */
  487. while (curnode)
  488. {
  489. Node* prevnode = curnode;
  490. curnode = TreeNextElement(t, curnode);
  491. /* if (curnode)
  492. printf("content int %d\n", *(int*)(curnode->content)); */
  493. if (prevnode && curnode && (*(int*)(curnode->content) < *(int*)(prevnode->content)))
  494. {
  495. printf("out of order %d < %d\n", *(int*)(curnode->content), *(int*)(prevnode->content));
  496. }
  497. if (curnode && (lookfor == *(int*)(curnode->content)))
  498. printf("missing item %d actually found\n", lookfor);
  499. }
  500. printf("End traverse %d\n", rc);
  501. return rc;
  502. }
  503. int test(int limit)
  504. {
  505. int i, *ip, *todelete;
  506. Node* current = NULL;
  507. Tree* t = TreeInitialize(TreeIntCompare);
  508. int rc = 0;
  509. printf("Tree initialized\n");
  510. srand(time(NULL));
  511. ip = malloc(sizeof(int));
  512. *ip = 2;
  513. TreeAdd(t, (void*)ip, sizeof(int));
  514. check(t);
  515. i = 2;
  516. void* result = TreeRemove(t, (void*)&i);
  517. if (result)
  518. free(result);
  519. int actual[limit];
  520. for (i = 0; i < limit; i++)
  521. {
  522. void* replaced = NULL;
  523. ip = malloc(sizeof(int));
  524. *ip = rand();
  525. replaced = TreeAdd(t, (void*)ip, sizeof(int));
  526. if (replaced) /* duplicate */
  527. {
  528. free(replaced);
  529. actual[i] = -1;
  530. }
  531. else
  532. actual[i] = *ip;
  533. if (i==5)
  534. todelete = ip;
  535. printf("Tree element added %d\n", *ip);
  536. if (1 % 1000 == 0)
  537. {
  538. rc = check(t);
  539. printf("%d elements, check result %d\n", i+1, rc);
  540. if (rc != 0)
  541. return 88;
  542. }
  543. }
  544. check(t);
  545. for (i = 0; i < limit; i++)
  546. {
  547. int parm = actual[i];
  548. if (parm == -1)
  549. continue;
  550. Node* found = TreeFind(t, (void*)&parm);
  551. if (found)
  552. printf("Tree find %d %d\n", parm, *(int*)(found->content));
  553. else
  554. {
  555. printf("%d not found\n", parm);
  556. traverse(t, parm);
  557. return -2;
  558. }
  559. }
  560. check(t);
  561. for (i = limit -1; i >= 0; i--)
  562. {
  563. int parm = actual[i];
  564. void *found;
  565. if (parm == -1) /* skip duplicate */
  566. continue;
  567. found = TreeRemove(t, (void*)&parm);
  568. if (found)
  569. {
  570. printf("%d Tree remove %d %d\n", i, parm, *(int*)(found));
  571. free(found);
  572. }
  573. else
  574. {
  575. int count = 0;
  576. printf("%d %d not found\n", i, parm);
  577. traverse(t, parm);
  578. for (i = 0; i < limit; i++)
  579. if (actual[i] == parm)
  580. ++count;
  581. printf("%d occurs %d times\n", parm, count);
  582. return -2;
  583. }
  584. if (i % 1000 == 0)
  585. {
  586. rc = check(t);
  587. printf("%d elements, check result %d\n", i+1, rc);
  588. if (rc != 0)
  589. return 88;
  590. }
  591. }
  592. printf("finished\n");
  593. return 0;
  594. }
  595. int main(int argc, char *argv[])
  596. {
  597. int rc = 0;
  598. while (rc == 0)
  599. rc = test(999999);
  600. }
  601. #endif