avl.c 17 KB

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