bintree.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /**
  2. \ingroup lub
  3. \defgroup lub_bintree bintree
  4. @{
  5. \brief This interface provides a facility which enables a client to
  6. order and access a set of arbitary data in a binary "tree"
  7. Each "tree" is defined by a number of "clientnodes" which are
  8. ordered according to a client defined "key".
  9. A "clientkey" is a client specific entity which can be compared
  10. with a "clientnode" to determine which is the "greatest". In order
  11. to do this the client needs provide a comparison function for
  12. comparing a "clientnode" with a "clientkey", and a function to
  13. convert a "clientnode" into a "clientkey".
  14. The client is responsible for providing each "clientnode" in a
  15. tree. This will typically contain some client specific data, but
  16. will also need to contain a bintree "node" which is used to
  17. structurally relate each node to one another in the tree. A
  18. specific "node" may only belong to one tree at a time, but an
  19. individual "clientnode" may contain multiple of these if necessary.
  20. \par Implementation
  21. The implementation of this interface uses a top-down splaying algorithm.
  22. \par
  23. "Splay trees", or "self-adjusting search trees" are a simple and
  24. efficient data structure for storing an ordered set. The data
  25. structure consists of a binary tree, without parent pointers, and
  26. no additional fields. It allows searching, insertion, deletion,
  27. deletemin, deletemax, splitting, joining, and many other
  28. operations, all with amortized logarithmic performance. Since the
  29. trees adapt to the sequence of requests, their performance on real
  30. access patterns is typically even better. Splay trees are
  31. described in a number of texts and papers [1,2,3,4,5].
  32. \par
  33. The code here is adapted from simple top-down splay, at the bottom
  34. of page 669 of [3]. It can be obtained via anonymous ftp from
  35. spade.pc.cs.cmu.edu in directory /usr/sleator/public.
  36. \par
  37. The chief modification here is that the splay operation works even
  38. if the item being splayed is not in the tree, and even if the tree
  39. root of the tree is NULL. So the line:
  40. \par
  41. t = splay(i, t);
  42. \par
  43. causes it to search for item with key i in the tree rooted at t.
  44. If it's there, it is splayed to the root. If it isn't there,
  45. then the node put at the root is the last one before NULL that
  46. would have been reached in a normal binary search for i. (It's a
  47. neighbor of i in the tree.) This allows many other operations to
  48. be easily implemented.
  49. \par
  50. [1] "Fundamentals of data structures in C", Horowitz, Sahni,
  51. and Anderson-Freed, Computer Science Press, pp 542-547.
  52. \par
  53. [2] "Data Structures and Their Algorithms", Lewis and Denenberg,
  54. Harper Collins, 1991, pp 243-251.
  55. \par
  56. [3] "Self-adjusting Binary Search Trees" Sleator and Tarjan,
  57. JACM Volume 32, No 3, July 1985, pp 652-686.
  58. \par
  59. [4] "Data Structure and Algorithm Analysis", Mark Weiss,
  60. Benjamin Cummins, 1992, pp 119-130.
  61. \par
  62. [5] "Data Structures, Algorithms, and Performance", Derick Wood,
  63. Addison-Wesley, 1993, pp 367-375.
  64. \par
  65. The splay function is based on one written by Daniel Sleator, which is released
  66. in the public domain.
  67. \author Graeme McKerrell
  68. \date Created On : Fri Jan 23 12:50:18 2004
  69. \version TESTED
  70. */
  71. /*---------------------------------------------------------------
  72. HISTORY
  73. 7-Dec-2004 Graeme McKerrell
  74. Updated to use the "lub" prefix
  75. 27-Feb-2004 Graeme McKerrell
  76. updated to simplify node initialisation
  77. 9-Feb-2004 Graeme McKerrell
  78. updated to make the comparision function compare a "clientnode" and
  79. "key"
  80. Updated getkey() function to fill out a provides "key" from a "clientnode"
  81. 23-Jan-2004 Graeme McKerrell
  82. Initial version
  83. --------------------------------------------------------------
  84. Copyright (C) 2004 3Com Corporation. All Rights Reserved.
  85. **************************************************************** */
  86. #ifndef _lub_bintree_h
  87. #define _lub_bintree_h
  88. #include <stddef.h>
  89. /****************************************************************
  90. * TYPE DEFINITIONS
  91. **************************************************************** */
  92. /**
  93. * This type represents a bintree "node".
  94. * Typically the client will have a "clientnode" structure which
  95. * contains it's data. A bintree "node" is made one of the data
  96. * elements of that structure. When the tree is initialised the
  97. * client provides the offset into the structure of the
  98. * "node" which is to be used for that tree.
  99. */
  100. typedef struct lub_bintree_node_s lub_bintree_node_t;
  101. /**
  102. * CLIENTS MUSTN'T TOUCH THE CONTENTS OF THIS STRUCTURE
  103. */
  104. struct lub_bintree_node_s {
  105. /** internal */ lub_bintree_node_t *left;
  106. /** internal */ lub_bintree_node_t *right;
  107. };
  108. /**
  109. * This type defines a callback function which will compare two "keys"
  110. * with each other
  111. *
  112. * \param clientnode the client node to compare
  113. * \param clientkey the key to compare with a node
  114. *
  115. * \return
  116. * <0 if clientnode < clientkey;
  117. * 0 if clientnode == clientkey;
  118. * >0 if clientnode > clientkey
  119. */
  120. typedef int
  121. lub_bintree_compare_fn(const void *clientnode, const void *clientkey);
  122. /**
  123. * This is used to size the key storage area for an opaque key.
  124. * If any client requires a greater storage size then this will need to
  125. * be increased.
  126. */
  127. #define lub_bintree_MAX_KEY_STORAGE (200)
  128. /**
  129. * This is used to declare an opaque key structure
  130. * Typically a client would declare their own non-opaque structure
  131. * which they would fill out appropriately
  132. */
  133. typedef struct lub_bintree_key_s lub_bintree_key_t;
  134. /**
  135. * CLIENTS MUSTN'T TOUCH THE CONTENTS OF THIS STRUCTURE
  136. */
  137. struct lub_bintree_key_s {
  138. /** internal */ char storage[lub_bintree_MAX_KEY_STORAGE];
  139. /** internal */ int magic;
  140. };
  141. /**
  142. * This type defines a callback function which will convert a client's "node"
  143. * into a search "key"
  144. *
  145. * \param clientnode the node from which to derive a key
  146. * \param key a reference to the key to fill out
  147. *
  148. * \return
  149. * A "key" which corresponds the "node" in this view
  150. */
  151. typedef void
  152. lub_bintree_getkey_fn(const void *clientnode, lub_bintree_key_t * key);
  153. /**
  154. * This type represents an binary tree instance
  155. */
  156. typedef struct lub_bintree_s lub_bintree_t;
  157. /**
  158. * CLIENTS MUSTN'T TOUCH THE CONTENTS OF THIS STRUCTURE
  159. */
  160. struct lub_bintree_s {
  161. /** internal */ lub_bintree_node_t *root;
  162. /** internal */ size_t node_offset;
  163. /** internal */ lub_bintree_compare_fn *compareFn;
  164. /** internal */ lub_bintree_getkey_fn *getkeyFn;
  165. };
  166. /**
  167. * This is used to perform iterations of a tree
  168. */
  169. typedef struct lub_bintree_iterator_s lub_bintree_iterator_t;
  170. /**
  171. * CLIENTS MUSTN'T TOUCH THE CONTENTS OF THIS STRUCTURE
  172. */
  173. struct lub_bintree_iterator_s {
  174. /** internal */ lub_bintree_t *tree;
  175. /** internal */ lub_bintree_key_t key;
  176. };
  177. /****************************************************************
  178. * BINTREE OPERATIONS
  179. **************************************************************** */
  180. /**
  181. * This operation initialises an instance of a binary tree.
  182. *
  183. * \pre none
  184. *
  185. * \post The tree is ready to have client nodes inserted.
  186. */
  187. extern void lub_bintree_init(
  188. /**
  189. * the "tree" instance to initialise
  190. */
  191. lub_bintree_t * tree,
  192. /**
  193. * the offset of the bintree "node" structure within the
  194. * "clientnode" structure. This is typically passed
  195. * using the offsetof() macro.
  196. */
  197. size_t node_offset,
  198. /**
  199. * a comparison function for comparing a "clientnode"
  200. * with a "clientkey"
  201. */
  202. lub_bintree_compare_fn compareFn,
  203. /**
  204. * a function which will fill out a "key" from a clientnode
  205. */
  206. lub_bintree_getkey_fn getkeyFn);
  207. /**
  208. * This operation is called to initialise a "clientnode" ready for
  209. * insertion into a tree. This is only required once after the memory
  210. * for a node has been allocated.
  211. *
  212. * \pre none
  213. *
  214. * \post The node is ready to be inserted into a tree.
  215. */
  216. extern void lub_bintree_node_init(
  217. /**
  218. * the bintree node to initialise
  219. */
  220. lub_bintree_node_t * node);
  221. /*****************************************
  222. * NODE MANIPULATION OPERATIONS
  223. ***************************************** */
  224. /**
  225. * This operation adds a client node to the specified tree.
  226. *
  227. * \pre The tree must be initialised
  228. * \pre The clientnode must be initialised
  229. *
  230. * \return
  231. * 0 if the "clientnode" is added correctly to the tree.
  232. * If another "clientnode" already exists in the tree with the same key, then
  233. * -1 is returned, and the tree remains unchanged.
  234. *
  235. * \post If the bintree "node" is already part of a tree, then an
  236. * assert will fire.
  237. */
  238. extern int lub_bintree_insert(
  239. /**
  240. * the "tree" instance to invoke this operation upon
  241. */
  242. lub_bintree_t * tree,
  243. /**
  244. * a pointer to a client node. NB the tree can find the
  245. * necessary lub_BintreeNodeT from it's stored offset.
  246. */
  247. void *clientnode);
  248. /**
  249. * This operation removes a "clientnode" from the specified "tree"
  250. *
  251. * \pre The tree must be initialised
  252. * \pre The clientnode must be initialised
  253. *
  254. * \post The "clientnode" will no longer be part of the specified tree, and will be
  255. * made available for re-insertion
  256. * \post If the clientnode is not present in the specified tree, then an
  257. * assert will fire.
  258. */
  259. extern void lub_bintree_remove(
  260. /**
  261. * the "tree" instance to invoke this operation upon
  262. */
  263. lub_bintree_t * tree,
  264. /**
  265. * the node to remove
  266. */
  267. void *clientnode);
  268. /*****************************************
  269. * NODE RETRIEVAL OPERATIONS
  270. ***************************************** */
  271. /**
  272. * This operation returns the first "clientnode" present in the specified "tree"
  273. *
  274. * \pre The tree must be initialised
  275. *
  276. * \return
  277. * "clientnode" instance or NULL if no nodes are present in this tree.
  278. */
  279. extern void *lub_bintree_findfirst(
  280. /**
  281. * the "tree" instance to invoke this operation upon
  282. */
  283. lub_bintree_t * tree);
  284. /**
  285. * This operation returns the last "clientnode" present in the specified "tree"
  286. *
  287. * \pre The tree must be initialised
  288. *
  289. * \return
  290. * "clientnode" instance or NULL if no nodes are present in this tree.
  291. */
  292. extern void *lub_bintree_findlast(
  293. /**
  294. * the "tree" instance to invoke this operation upon
  295. */
  296. lub_bintree_t * tree);
  297. /**
  298. * This operation searches the specified "tree" for a "clientnode" which matches the
  299. * specified "key"
  300. *
  301. * \pre The tree must be initialised
  302. *
  303. * \return
  304. * "clientnode" instance or NULL if no node is found.
  305. */
  306. extern void *lub_bintree_find(
  307. /**
  308. * the "tree" instance to invoke this operation upon
  309. */
  310. lub_bintree_t * tree,
  311. /**
  312. * the "key" to search with
  313. */
  314. const void *key);
  315. /**
  316. * This operation searches the specified "tree" for a "clientnode" which is
  317. * the one which logically follows the specified "key"
  318. *
  319. * A "clientnode" with the specified "key" doesn't need to be in the tree.
  320. *
  321. * \pre The tree must be initialised
  322. *
  323. * \return
  324. * "clientnode" instance or NULL if no node is found.
  325. */
  326. extern void *lub_bintree_findnext(
  327. /**
  328. * the "tree" instance to invoke this operation upon
  329. */
  330. lub_bintree_t * tree,
  331. /**
  332. * the "key" to search with
  333. */
  334. const void *key);
  335. /**
  336. * This operation searches the specified "tree" for a "clientnode" which is
  337. * the one which logically preceeds the specified "key"
  338. *
  339. * A "clientnode" with the specified "key" doesn't need to be in the tree.
  340. *
  341. * \pre The tree must be initialised
  342. *
  343. * \return
  344. * "clientnode" instance or NULL if no node is found.
  345. */
  346. extern void *lub_bintree_findprevious(
  347. /**
  348. * the "tree" instance to invoke this operation upon
  349. */
  350. lub_bintree_t * tree,
  351. /**
  352. * the "key" to search with
  353. */
  354. const void *key);
  355. /*****************************************
  356. * ITERATION OPERATIONS
  357. ***************************************** */
  358. /**
  359. * This operation initialises an iterator. This can then be
  360. * subsequently used for iterating through a tree. This will work
  361. * even if the "clientnode" which defined the current iterator has been
  362. * removed before the next iterator operation.
  363. *
  364. * \pre The tree must be initialised
  365. * \pre The clientnode must be initialised and valid at the time of this call
  366. *
  367. * \post The interator instance will be updated to reference the position in the tree for the clientnode.
  368. */
  369. extern void lub_bintree_iterator_init(
  370. /**
  371. * the iterator instance to initialise
  372. */
  373. lub_bintree_iterator_t * iter,
  374. /**
  375. * the tree to associate with this iterator
  376. */
  377. lub_bintree_t * tree,
  378. /**
  379. * the starting point for the iteration
  380. */
  381. const void *clientnode);
  382. /**
  383. * This operation returns the next "clientnode" in an iteration.
  384. *
  385. * \pre The interator instance must have been initialised
  386. *
  387. * \return
  388. * "clientnode" instance or NULL if the iteration has reached the end of the
  389. * tree.
  390. *
  391. * \post The interator instance will be updated to reference the position in the tree for the returned value.
  392. */
  393. extern void *lub_bintree_iterator_next(
  394. /**
  395. * the iterator instance to invoke this operation upon.
  396. */
  397. lub_bintree_iterator_t * iter);
  398. /**
  399. * This operation returns the previous "clientnode" in an iteration.
  400. *
  401. * \pre The interator instance must have been initialised
  402. *
  403. * \return
  404. * "clientnode" instance or NULL if the iteration has reached the beginning
  405. * of the tree.
  406. *
  407. * \post The interator instance will be updated to reference the position in the tree for the returned value.
  408. */
  409. extern void *lub_bintree_iterator_previous(
  410. /**
  411. * the iterator instance to invoke this operation upon.
  412. */
  413. lub_bintree_iterator_t *
  414. iter);
  415. /**
  416. * This operation dumps the node list of the specified tree to stdout
  417. *
  418. * \pre The tree must be initialised
  419. *
  420. * \post The structure of the tree will be unaltered.
  421. */
  422. extern void lub_bintree_dump(
  423. /**
  424. * the "tree" instance to invoke this operation upon
  425. */
  426. lub_bintree_t * tree);
  427. #endif /* _lub_bintree_h */
  428. /** @} */