avl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /* avl.c - routines to implement an avl tree */
  13. /*
  14. * Copyright (c) 1993 Regents of the University of Michigan.
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms are permitted
  18. * provided that this notice is preserved and that due credit is given
  19. * to the University of Michigan at Ann Arbor. The name of the University
  20. * may not be used to endorse or promote products derived from this
  21. * software without specific prior written permission. This software
  22. * is provided ``as is'' without express or implied warranty.
  23. */
  24. #if 0
  25. static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
  26. static char avl_version[] = "AVL library version 1.0\n";
  27. #endif
  28. #include <sys/types.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include "avl.h"
  32. #define ROTATERIGHT(x) { \
  33. Avlnode *tmp;\
  34. if ( *x == NULL || (*x)->avl_left == NULL ) {\
  35. (void) printf("RR error\n"); exit(1); \
  36. }\
  37. tmp = (*x)->avl_left;\
  38. (*x)->avl_left = tmp->avl_right;\
  39. tmp->avl_right = *x;\
  40. *x = tmp;\
  41. }
  42. #define ROTATELEFT(x) { \
  43. Avlnode *tmp;\
  44. if ( *x == NULL || (*x)->avl_right == NULL ) {\
  45. (void) printf("RL error\n"); exit(1); \
  46. }\
  47. tmp = (*x)->avl_right;\
  48. (*x)->avl_right = tmp->avl_left;\
  49. tmp->avl_left = *x;\
  50. *x = tmp;\
  51. }
  52. /*
  53. * ravl_insert - called from avl_insert() to do a recursive insert into
  54. * and balance of an avl tree.
  55. */
  56. static int
  57. ravl_insert(
  58. Avlnode **iroot,
  59. caddr_t data,
  60. int *taller,
  61. IFP fcmp, /* comparison function */
  62. IFP fdup, /* function to call for duplicates */
  63. int depth
  64. )
  65. {
  66. int rc, cmp, tallersub;
  67. Avlnode *l, *r;
  68. if ( *iroot == 0 ) {
  69. if ( (*iroot = (Avlnode *) malloc( sizeof( Avlnode ) ))
  70. == NULL ) {
  71. return( -1 );
  72. }
  73. (*iroot)->avl_left = 0;
  74. (*iroot)->avl_right = 0;
  75. (*iroot)->avl_bf = 0;
  76. (*iroot)->avl_data = data;
  77. *taller = 1;
  78. return( 0 );
  79. }
  80. cmp = (*fcmp)( data, (*iroot)->avl_data );
  81. /* equal - duplicate name */
  82. if ( cmp == 0 ) {
  83. *taller = 0;
  84. return( (*fdup)( (*iroot)->avl_data, data ) );
  85. }
  86. /* go right */
  87. else if ( cmp > 0 ) {
  88. rc = ravl_insert( &((*iroot)->avl_right), data, &tallersub,
  89. fcmp, fdup, depth );
  90. if ( tallersub )
  91. switch ( (*iroot)->avl_bf ) {
  92. case LH : /* left high - balance is restored */
  93. (*iroot)->avl_bf = EH;
  94. *taller = 0;
  95. break;
  96. case EH : /* equal height - now right heavy */
  97. (*iroot)->avl_bf = RH;
  98. *taller = 1;
  99. break;
  100. case RH : /* right heavy to start - right balance */
  101. r = (*iroot)->avl_right;
  102. switch ( r->avl_bf ) {
  103. case LH : /* double rotation left */
  104. l = r->avl_left;
  105. switch ( l->avl_bf ) {
  106. case LH : (*iroot)->avl_bf = EH;
  107. r->avl_bf = RH;
  108. break;
  109. case EH : (*iroot)->avl_bf = EH;
  110. r->avl_bf = EH;
  111. break;
  112. case RH : (*iroot)->avl_bf = LH;
  113. r->avl_bf = EH;
  114. break;
  115. }
  116. l->avl_bf = EH;
  117. ROTATERIGHT( (&r) )
  118. (*iroot)->avl_right = r;
  119. ROTATELEFT( iroot )
  120. *taller = 0;
  121. break;
  122. case EH : /* This should never happen */
  123. break;
  124. case RH : /* single rotation left */
  125. (*iroot)->avl_bf = EH;
  126. r->avl_bf = EH;
  127. ROTATELEFT( iroot )
  128. *taller = 0;
  129. break;
  130. }
  131. break;
  132. }
  133. else
  134. *taller = 0;
  135. }
  136. /* go left */
  137. else {
  138. rc = ravl_insert( &((*iroot)->avl_left), data, &tallersub,
  139. fcmp, fdup, depth );
  140. if ( tallersub )
  141. switch ( (*iroot)->avl_bf ) {
  142. case LH : /* left high to start - left balance */
  143. l = (*iroot)->avl_left;
  144. switch ( l->avl_bf ) {
  145. case LH : /* single rotation right */
  146. (*iroot)->avl_bf = EH;
  147. l->avl_bf = EH;
  148. ROTATERIGHT( iroot )
  149. *taller = 0;
  150. break;
  151. case EH : /* this should never happen */
  152. break;
  153. case RH : /* double rotation right */
  154. r = l->avl_right;
  155. switch ( r->avl_bf ) {
  156. case LH : (*iroot)->avl_bf = RH;
  157. l->avl_bf = EH;
  158. break;
  159. case EH : (*iroot)->avl_bf = EH;
  160. l->avl_bf = EH;
  161. break;
  162. case RH : (*iroot)->avl_bf = EH;
  163. l->avl_bf = LH;
  164. break;
  165. }
  166. r->avl_bf = EH;
  167. ROTATELEFT( (&l) )
  168. (*iroot)->avl_left = l;
  169. ROTATERIGHT( iroot )
  170. *taller = 0;
  171. break;
  172. }
  173. break;
  174. case EH : /* equal height - now left heavy */
  175. (*iroot)->avl_bf = LH;
  176. *taller = 1;
  177. break;
  178. case RH : /* right high - balance is restored */
  179. (*iroot)->avl_bf = EH;
  180. *taller = 0;
  181. break;
  182. }
  183. else
  184. *taller = 0;
  185. }
  186. return( rc );
  187. }
  188. /*
  189. * avl_insert -- insert a node containing data data into the avl tree
  190. * with root root. fcmp is a function to call to compare the data portion
  191. * of two nodes. it should take two arguments and return <, >, or == 0,
  192. * depending on whether its first argument is <, >, or == its second
  193. * argument (like strcmp, e.g.). fdup is a function to call when a duplicate
  194. * node is inserted. it should return 0, or -1 and its return value
  195. * will be the return value from avl_insert in the case of a duplicate node.
  196. * the function will be called with the original node's data as its first
  197. * argument and with the incoming duplicate node's data as its second
  198. * argument. this could be used, for example, to keep a count with each
  199. * node.
  200. *
  201. * NOTE: this routine may malloc memory
  202. */
  203. int
  204. avl_insert(
  205. Avlnode **root,
  206. caddr_t data,
  207. IFP fcmp,
  208. IFP fdup
  209. )
  210. {
  211. int taller;
  212. return( ravl_insert( root, data, &taller, fcmp, fdup, 0 ) );
  213. }
  214. /*
  215. * right_balance() - called from delete when root's right subtree has
  216. * been shortened because of a deletion.
  217. */
  218. static int
  219. right_balance( Avlnode **root )
  220. {
  221. int shorter= 0;
  222. Avlnode *r, *l;
  223. switch( (*root)->avl_bf ) {
  224. case RH: /* was right high - equal now */
  225. (*root)->avl_bf = EH;
  226. shorter = 1;
  227. break;
  228. case EH: /* was equal - left high now */
  229. (*root)->avl_bf = LH;
  230. shorter = 0;
  231. break;
  232. case LH: /* was right high - balance */
  233. l = (*root)->avl_left;
  234. switch ( l->avl_bf ) {
  235. case RH : /* double rotation left */
  236. r = l->avl_right;
  237. switch ( r->avl_bf ) {
  238. case RH :
  239. (*root)->avl_bf = EH;
  240. l->avl_bf = LH;
  241. break;
  242. case EH :
  243. (*root)->avl_bf = EH;
  244. l->avl_bf = EH;
  245. break;
  246. case LH :
  247. (*root)->avl_bf = RH;
  248. l->avl_bf = EH;
  249. break;
  250. }
  251. r->avl_bf = EH;
  252. ROTATELEFT( (&l) )
  253. (*root)->avl_left = l;
  254. ROTATERIGHT( root )
  255. shorter = 1;
  256. break;
  257. case EH : /* right rotation */
  258. (*root)->avl_bf = LH;
  259. l->avl_bf = RH;
  260. ROTATERIGHT( root );
  261. shorter = 0;
  262. break;
  263. case LH : /* single rotation right */
  264. (*root)->avl_bf = EH;
  265. l->avl_bf = EH;
  266. ROTATERIGHT( root )
  267. shorter = 1;
  268. break;
  269. }
  270. break;
  271. }
  272. return( shorter );
  273. }
  274. /*
  275. * left_balance() - called from delete when root's left subtree has
  276. * been shortened because of a deletion.
  277. */
  278. static int
  279. left_balance( Avlnode **root )
  280. {
  281. int shorter= 0;
  282. Avlnode *r, *l;
  283. switch( (*root)->avl_bf ) {
  284. case LH: /* was left high - equal now */
  285. (*root)->avl_bf = EH;
  286. shorter = 1;
  287. break;
  288. case EH: /* was equal - right high now */
  289. (*root)->avl_bf = RH;
  290. shorter = 0;
  291. break;
  292. case RH: /* was right high - balance */
  293. r = (*root)->avl_right;
  294. switch ( r->avl_bf ) {
  295. case LH : /* double rotation left */
  296. l = r->avl_left;
  297. switch ( l->avl_bf ) {
  298. case LH :
  299. (*root)->avl_bf = EH;
  300. r->avl_bf = RH;
  301. break;
  302. case EH :
  303. (*root)->avl_bf = EH;
  304. r->avl_bf = EH;
  305. break;
  306. case RH :
  307. (*root)->avl_bf = LH;
  308. r->avl_bf = EH;
  309. break;
  310. }
  311. l->avl_bf = EH;
  312. ROTATERIGHT( (&r) )
  313. (*root)->avl_right = r;
  314. ROTATELEFT( root )
  315. shorter = 1;
  316. break;
  317. case EH : /* single rotation left */
  318. (*root)->avl_bf = RH;
  319. r->avl_bf = LH;
  320. ROTATELEFT( root );
  321. shorter = 0;
  322. break;
  323. case RH : /* single rotation left */
  324. (*root)->avl_bf = EH;
  325. r->avl_bf = EH;
  326. ROTATELEFT( root )
  327. shorter = 1;
  328. break;
  329. }
  330. break;
  331. }
  332. return( shorter );
  333. }
  334. /*
  335. * ravl_delete() - called from avl_delete to do recursive deletion of a
  336. * node from an avl tree. It finds the node recursively, deletes it,
  337. * and returns shorter if the tree is shorter after the deletion and
  338. * rebalancing.
  339. */
  340. static caddr_t
  341. ravl_delete(
  342. Avlnode **root,
  343. caddr_t data,
  344. IFP fcmp,
  345. int *shorter
  346. )
  347. {
  348. int shortersubtree = 0;
  349. int cmp;
  350. caddr_t savedata;
  351. Avlnode *minnode, *savenode;
  352. if ( *root == NULLAVL )
  353. return( 0 );
  354. cmp = (*fcmp)( data, (*root)->avl_data );
  355. /* found it! */
  356. if ( cmp == 0 ) {
  357. savenode = *root;
  358. savedata = savenode->avl_data;
  359. /* simple cases: no left child */
  360. if ( (*root)->avl_left == 0 ) {
  361. *root = (*root)->avl_right;
  362. *shorter = 1;
  363. free( (char *) savenode );
  364. return( savedata );
  365. /* no right child */
  366. } else if ( (*root)->avl_right == 0 ) {
  367. *root = (*root)->avl_left;
  368. *shorter = 1;
  369. free( (char *) savenode );
  370. return( savedata );
  371. }
  372. /*
  373. * avl_getmin will return to us the smallest node greater
  374. * than the one we are trying to delete. deleting this node
  375. * from the right subtree is guaranteed to end in one of the
  376. * simple cases above.
  377. */
  378. minnode = (*root)->avl_right;
  379. while ( minnode->avl_left != NULLAVL )
  380. minnode = minnode->avl_left;
  381. /* swap the data */
  382. (*root)->avl_data = minnode->avl_data;
  383. minnode->avl_data = savedata;
  384. savedata = ravl_delete( &(*root)->avl_right, data, fcmp,
  385. &shortersubtree );
  386. if ( shortersubtree )
  387. *shorter = right_balance( root );
  388. else
  389. *shorter = 0;
  390. /* go left */
  391. } else if ( cmp < 0 ) {
  392. if ( (savedata = ravl_delete( &(*root)->avl_left, data, fcmp,
  393. &shortersubtree )) == 0 ) {
  394. *shorter = 0;
  395. return( 0 );
  396. }
  397. /* left subtree shorter? */
  398. if ( shortersubtree )
  399. *shorter = left_balance( root );
  400. else
  401. *shorter = 0;
  402. /* go right */
  403. } else {
  404. if ( (savedata = ravl_delete( &(*root)->avl_right, data, fcmp,
  405. &shortersubtree )) == 0 ) {
  406. *shorter = 0;
  407. return( 0 );
  408. }
  409. if ( shortersubtree )
  410. *shorter = right_balance( root );
  411. else
  412. *shorter = 0;
  413. }
  414. return( savedata );
  415. }
  416. /*
  417. * avl_delete() - deletes the node containing data (according to fcmp) from
  418. * the avl tree rooted at root.
  419. */
  420. caddr_t
  421. avl_delete( Avlnode **root, caddr_t data, IFP fcmp )
  422. {
  423. int shorter;
  424. return( ravl_delete( root, data, fcmp, &shorter ) );
  425. }
  426. static int
  427. avl_inapply( Avlnode *root, IFP fn, caddr_t arg, int stopflag )
  428. {
  429. if ( root == 0 )
  430. return( AVL_NOMORE );
  431. if ( root->avl_left != 0 )
  432. if ( avl_inapply( root->avl_left, fn, arg, stopflag )
  433. == stopflag )
  434. return( stopflag );
  435. if ( (*fn)( root->avl_data, arg ) == stopflag )
  436. return( stopflag );
  437. if ( root->avl_right == 0 )
  438. return( AVL_NOMORE );
  439. else
  440. return( avl_inapply( root->avl_right, fn, arg, stopflag ) );
  441. }
  442. static int
  443. avl_postapply( Avlnode *root, IFP fn, caddr_t arg, int stopflag )
  444. {
  445. if ( root == 0 )
  446. return( AVL_NOMORE );
  447. if ( root->avl_left != 0 )
  448. if ( avl_postapply( root->avl_left, fn, arg, stopflag )
  449. == stopflag )
  450. return( stopflag );
  451. if ( root->avl_right != 0 )
  452. if ( avl_postapply( root->avl_right, fn, arg, stopflag )
  453. == stopflag )
  454. return( stopflag );
  455. return( (*fn)( root->avl_data, arg ) );
  456. }
  457. static int
  458. avl_preapply( Avlnode *root, IFP fn, caddr_t arg, int stopflag )
  459. {
  460. if ( root == 0 )
  461. return( AVL_NOMORE );
  462. if ( (*fn)( root->avl_data, arg ) == stopflag )
  463. return( stopflag );
  464. if ( root->avl_left != 0 )
  465. if ( avl_preapply( root->avl_left, fn, arg, stopflag )
  466. == stopflag )
  467. return( stopflag );
  468. if ( root->avl_right == 0 )
  469. return( AVL_NOMORE );
  470. else
  471. return( avl_preapply( root->avl_right, fn, arg, stopflag ) );
  472. }
  473. /*
  474. * avl_apply -- avl tree root is traversed, function fn is called with
  475. * arguments arg and the data portion of each node. if fn returns stopflag,
  476. * the traversal is cut short, otherwise it continues. Do not use -6 as
  477. * a stopflag, as this is what is used to indicate the traversal ran out
  478. * of nodes.
  479. */
  480. int
  481. avl_apply(
  482. Avlnode *root,
  483. IFP fn,
  484. caddr_t arg,
  485. int stopflag,
  486. int type
  487. )
  488. {
  489. switch ( type ) {
  490. case AVL_INORDER:
  491. return( avl_inapply( root, fn, arg, stopflag ) );
  492. case AVL_PREORDER:
  493. return( avl_preapply( root, fn, arg, stopflag ) );
  494. case AVL_POSTORDER:
  495. return( avl_postapply( root, fn, arg, stopflag ) );
  496. default:
  497. fprintf( stderr, "Invalid traversal type %d\n", type );
  498. return( -1 );
  499. }
  500. /* NOTREACHED */
  501. }
  502. /*
  503. * avl_prefixapply - traverse avl tree root, applying function fprefix
  504. * to any nodes that match. fcmp is called with data as its first arg
  505. * and the current node's data as its second arg. it should return
  506. * 0 if they match, < 0 if data is less, and > 0 if data is greater.
  507. * the idea is to efficiently find all nodes that are prefixes of
  508. * some key... Like avl_apply, this routine also takes a stopflag
  509. * and will return prematurely if fmatch returns this value. Otherwise,
  510. * AVL_NOMORE is returned.
  511. */
  512. int
  513. avl_prefixapply(
  514. Avlnode *root,
  515. caddr_t data,
  516. IFP fmatch,
  517. caddr_t marg,
  518. IFP fcmp,
  519. caddr_t carg,
  520. int stopflag
  521. )
  522. {
  523. int cmp;
  524. if ( root == 0 )
  525. return( AVL_NOMORE );
  526. cmp = (*fcmp)( data, root->avl_data, carg );
  527. if ( cmp == 0 ) {
  528. if ( (*fmatch)( root->avl_data, marg ) == stopflag )
  529. return( stopflag );
  530. if ( root->avl_left != 0 )
  531. if ( avl_prefixapply( root->avl_left, data, fmatch,
  532. marg, fcmp, carg, stopflag ) == stopflag )
  533. return( stopflag );
  534. if ( root->avl_right != 0 )
  535. return( avl_prefixapply( root->avl_right, data, fmatch,
  536. marg, fcmp, carg, stopflag ) );
  537. else
  538. return( AVL_NOMORE );
  539. } else if ( cmp < 0 ) {
  540. if ( root->avl_left != 0 )
  541. return( avl_prefixapply( root->avl_left, data, fmatch,
  542. marg, fcmp, carg, stopflag ) );
  543. } else {
  544. if ( root->avl_right != 0 )
  545. return( avl_prefixapply( root->avl_right, data, fmatch,
  546. marg, fcmp, carg, stopflag ) );
  547. }
  548. return( AVL_NOMORE );
  549. }
  550. /*
  551. * avl_free -- traverse avltree root, freeing the memory it is using.
  552. * the dfree() is called to free the data portion of each node. The
  553. * number of items actually freed is returned.
  554. */
  555. int
  556. avl_free( Avlnode *root, IFP dfree )
  557. {
  558. int nleft, nright;
  559. if ( root == 0 )
  560. return( 0 );
  561. nleft = nright = 0;
  562. if ( root->avl_left != 0 )
  563. nleft = avl_free( root->avl_left, dfree );
  564. if ( root->avl_right != 0 )
  565. nright = avl_free( root->avl_right, dfree );
  566. if ( dfree )
  567. (*dfree)( root->avl_data );
  568. free( (char *)root );
  569. return( nleft + nright + 1 );
  570. }
  571. /*
  572. * avl_find -- search avltree root for a node with data data. the function
  573. * cmp is used to compare things. it is called with data as its first arg
  574. * and the current node data as its second. it should return 0 if they match,
  575. * < 0 if arg1 is less than arg2 and > 0 if arg1 is greater than arg2.
  576. */
  577. caddr_t
  578. avl_find( Avlnode *root, caddr_t data, IFP fcmp )
  579. {
  580. int cmp;
  581. while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) {
  582. if ( cmp < 0 )
  583. root = root->avl_left;
  584. else
  585. root = root->avl_right;
  586. }
  587. return( root ? root->avl_data : 0 );
  588. }
  589. /*
  590. * avl_find_lin -- search avltree root linearly for a node with data data.
  591. * the function cmp is used to compare things. it is called with data as its
  592. * first arg and the current node data as its second. it should return 0 if
  593. * they match, non-zero otherwise.
  594. */
  595. caddr_t
  596. avl_find_lin( Avlnode *root, caddr_t data, IFP fcmp )
  597. {
  598. caddr_t res;
  599. if ( root == 0 )
  600. return( NULL );
  601. if ( (*fcmp)( data, root->avl_data ) == 0 )
  602. return( root->avl_data );
  603. if ( root->avl_left != 0 )
  604. if ( (res = avl_find_lin( root->avl_left, data, fcmp ))
  605. != NULL )
  606. return( res );
  607. if ( root->avl_right == 0 )
  608. return( NULL );
  609. else
  610. return( avl_find_lin( root->avl_right, data, fcmp ) );
  611. }
  612. static caddr_t *avl_list = (caddr_t *)0;
  613. static int avl_maxlist = 0;
  614. static int avl_nextlist = 0;
  615. #define AVL_GRABSIZE 100
  616. /* ARGSUSED */
  617. static int
  618. avl_buildlist( caddr_t data, int arg )
  619. {
  620. static int slots = 0;
  621. if ( avl_list == (caddr_t *) 0 ) {
  622. avl_list = (caddr_t *) malloc(AVL_GRABSIZE * sizeof(caddr_t));
  623. slots = AVL_GRABSIZE;
  624. avl_maxlist = 0;
  625. } else if ( avl_maxlist == slots ) {
  626. slots += AVL_GRABSIZE;
  627. avl_list = (caddr_t *) realloc( (char *) avl_list,
  628. (unsigned) slots * sizeof(caddr_t));
  629. }
  630. avl_list[ avl_maxlist++ ] = data;
  631. return( 0 );
  632. }
  633. /*
  634. * avl_getfirst() and avl_getnext() are provided as alternate tree
  635. * traversal methods, to be used when a single function cannot be
  636. * provided to be called with every node in the tree. avl_getfirst()
  637. * traverses the tree and builds a linear list of all the nodes,
  638. * returning the first node. avl_getnext() returns the next thing
  639. * on the list built by avl_getfirst(). This means that avl_getfirst()
  640. * can take a while, and that the tree should not be messed with while
  641. * being traversed in this way, and that multiple traversals (even of
  642. * different trees) cannot be active at once.
  643. */
  644. caddr_t
  645. avl_getfirst( Avlnode *root )
  646. {
  647. if ( avl_list ) {
  648. free( (char *) avl_list);
  649. avl_list = (caddr_t *) 0;
  650. }
  651. avl_maxlist = 0;
  652. avl_nextlist = 0;
  653. if ( root == 0 )
  654. return( 0 );
  655. (void) avl_apply( root, avl_buildlist, (caddr_t) 0, -1, AVL_INORDER );
  656. if(avl_list && avl_list[avl_nextlist++]){
  657. return avl_list[avl_nextlist];
  658. } else {
  659. return( NULL );
  660. }
  661. }
  662. caddr_t
  663. avl_getnext()
  664. {
  665. if ( avl_list == 0 )
  666. return( 0 );
  667. if ( avl_nextlist == avl_maxlist ) {
  668. free( (caddr_t) avl_list);
  669. avl_list = (caddr_t *) 0;
  670. return( 0 );
  671. }
  672. return( avl_list[ avl_nextlist++ ] );
  673. }
  674. int avl_dup_error()
  675. {
  676. return( -1 );
  677. }
  678. int avl_dup_ok()
  679. {
  680. return( 0 );
  681. }