home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 11146 < prev    next >
Internet Message Format  |  1994-08-20  |  50KB

  1. Path: wupost!udel!news.udel.edu!darwin.sura.net!howland.reston.ans.net!agate!darkstar.UCSC.EDU!news.hal.COM!decwrl!src.dec.com!crl.dec.com!nntpd.lkg.dec.com!mrnews.mro.dec.com!zuunix.zuo.dec.com!pbs
  2. From: pbs@zuunix.zuo.dec.com (Philip Shearer @ZUO-DC EBS-Team)
  3. Newsgroups: alt.sources
  4. Subject: tsearch(3) replacment with tseachAVL btree
  5. Followup-To: comp.unix.programmer
  6. Date: 19 Aug 1994 16:14:03 GMT
  7. Organization: Digital Equipment Corporation - Marlboro, MA
  8. Lines: 1842
  9. Message-ID: <332lob$9j5@mrnews.mro.dec.com>
  10. NNTP-Posting-Host: zuunix.zuo.dec.com
  11. Summary: C source replacment of tsearch(3) with tseachAVL() btree.
  12. Keywords: tsearch AVL btree
  13. X-Newsreader: Tin 1.1 PL3
  14.  
  15. Archive-name: tsearchAVL
  16. Submitted-by: pbs@lmrln.demon.co.uk
  17.  
  18. echo "-------------------------X---CUT HERE---X--------------------------------"
  19. echo "This is a shell archive (shar)  file."
  20. echo "Fri Aug 19 17:35:03 MET DST 1994"
  21. echo "To unpack. Remove everything above including the line 'CUT HERE',"
  22. echo "save in a file, and unpack with 'sh file'."
  23. echo this shar file contains:
  24. echo  -rw-r--r--   1 pbs      users       4734 Aug 19 17:33 README 
  25. echo  -rw-r--r--   1 pbs      users       3447 Aug 19 17:06 avltree.h 
  26. echo  -rw-r--r--   1 pbs      users      24344 Aug 19 17:04 avltree.c 
  27. echo  -rw-r--r--   1 pbs      users       4894 Aug 19 14:32 atest.c 
  28. echo  -rw-r--r--   1 pbs      users       5531 Aug 17 14:43 btest.c 
  29. echo  -rw-r--r--   1 pbs      users        961 Aug 19 15:32 makefile 
  30. echo 
  31. echo "If this archive is complete, you will see the following message at the end:"
  32. echo shar: End of shell archive.
  33. echo 
  34. if test -f README -a README != "-c" ; then
  35.     echo shar: Will not over-write existing file "README" 
  36. else
  37. echo shar: Extracting README \(      4735 characters\) 
  38. sed 's/^X//'<< 'END_OF_README' > README
  39. XSubject: tsearch(3) replacment with tseachAVL btree
  40. XFollowup-To: comp.unix.programmer
  41. X
  42. XArchive-name: tsearchAVL
  43. XSubmitted-by: pbs@lmrln.demon.co.uk
  44. X
  45. XCopyright (c) 1992 Lomarline Ltd 
  46. X@(#)avltree README 1.2 8/16/94 14:34:18 LMRN
  47. X_POSIX_SOURCE complient.
  48. XCompiler(s)  : SunOS 4.1, System V Rel 3, OSF1
  49. X
  50. XPermission to use, copy, modify, distribute, and sell this software and
  51. Xits documentation for any purpose is hereby granted without fee, provided
  52. Xthat the above copyright notices and this permission notice appear in
  53. Xall copies of the software and related documentation.
  54. X
  55. XTHE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  56. XEXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  57. XWARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  58. X
  59. XIN NO EVENT SHALL LOMARLINE LTD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  60. XINDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  61. XRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  62. XPOSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR
  63. XIN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  64. X
  65. X
  66. X
  67. X
  68. XReplacement functions to perform tsearch etc, with a AVL balanced tree
  69. Xstructure. AVL balance is when the height of left and right subtree
  70. Xfrom each node differ by one at most.
  71. X
  72. X  void *tsearchAVL( void *key, void **rootp, int (*compar)() );
  73. X  void *tfindAVL( void *key, void **rootp, int (*compar)() );
  74. X  void *tdeleteAVL( void *key, void **rootp, int (*compar)() );
  75. X  void twalkAVL( void *root, void (*action)() );
  76. X
  77. XSee the manual entries for tsearch(3) for more details.
  78. X
  79. XHow to use this code:
  80. X---------------------
  81. X
  82. XThe make files and the example programs sould be self explanitory.
  83. X
  84. XIf you wish to use the avltree.c module as strait replacement for
  85. Xthe standard library calls compile the module with -DAVL.
  86. X
  87. XAdd #include "avltree.h" to your source file and recomplie your
  88. Xsource with -DAVL and link in the avltree.o module.
  89. X
  90. XThe header file "avltree.h" has in it #defines which replace 
  91. Xthe standard tsearch() with tsearchAVL() etc if the AVL flag is set.
  92. X
  93. X
  94. XIf you wish to take advantage of tdeleteAVL returning a pointer to
  95. Xthe information of the deleted node so that it can be freed then 
  96. Xcompile the avltree.c module without the -DAVL. 
  97. X
  98. XAdd #include "avltree.h" to your source files, alter the tsearch() to
  99. XtsearchAVL() etc and then compile your source without the -DAVL flag
  100. Xand  link in the avltree.o module.
  101. X
  102. XWARNING:
  103. X--------
  104. X
  105. XWith reference to the above.
  106. X
  107. XThere is one area where theses functions move away from the standard.
  108. XIf the module avltree.c is compiled without the AVL flag set then
  109. Xthe tdelete function returns a pointer to the information containd in the
  110. Xdeleted node rather than the address of a pointer to the parent node
  111. Xinformation.
  112. X
  113. XThis is because the parent node is not of much use in an AVL tree.
  114. XThe pointer to the information contained in the deleted not is of more 
  115. Xuse because this information can then be freed by the user application
  116. Xif necessary.
  117. X
  118. XWhat is the advantage of an AVL tree?
  119. X-------------------------------------
  120. X
  121. XThere are two fundemental problems with a B tree.
  122. X
  123. XThe furthur away that the data is form random when placed into a btree
  124. Xthe greater the liklyhood of degeneration. In the worst case if the
  125. Xdata is sorted the the data will not be in a tree but a linked list.
  126. X
  127. XOver time as inserts and deletes are made a tree structure may
  128. Xdegenerate.
  129. X
  130. XAVL trees take care of both theses problems becase the software
  131. Xautomaticaly rebalances the tree so that it is never more than one level
  132. Xaway from balance.
  133. X
  134. XSo the AVL tree will automate away the need to worry about the ordering
  135. Xof data placed into a btree.
  136. X
  137. XUnless your data is close to random and you do not intend to delete
  138. Xand insert more than you find then tsearchAVL will probably 
  139. Xbe usefull for you.
  140. X
  141. XCredits
  142. X-------
  143. X
  144. XThis software was origenally written by Neil Barker for a project
  145. Xwhich went belly up for lack of funds.
  146. X
  147. XI, Philip Shearer modified the source for clartity and so that the
  148. Xreturns were consistent with those of the standard library.
  149. X
  150. XTo help find the bugs I looked at:
  151. XAVL Trees V2.0, 5-September-1993 Paul Vixie, a copy of which is kept on
  152. Xgatekeeper.dec.com 
  153. X93.09.06 pub/usenet/comp.sources.unix/volume27/avl-subs/part01
  154. X
  155. X(If we had known about an earlier version of this code back in 1990 we 
  156. Xwould never have written our own!)
  157. X
  158. XNeil used the same book as Paul Vixie
  159. X
  160. XAlgorithms & Data Structures
  161. XNiklaus Wirth, Prentice-Hall 1986, ISBN 0-13-022005-1.
  162. X
  163. XWhich explains why the code looks some what similar.
  164. XWhile debugging the code I did not have A&DS to hand so I used one called:
  165. X
  166. XData structures in ANSI C
  167. XS. Sengupta and P. Edwards, Academic Press 1991, ISBN 0-12-635655-1.
  168. X
  169. END_OF_README
  170. if test       4735 -ne `wc -c < README `; then
  171.     echo shar: \"README\" unpacked with wrong size!       4735 
  172. fi
  173. # end of overwriting check
  174. fi
  175. if test -f avltree.h -a README != "-c" ; then
  176.     echo shar: Will not over-write existing file "avltree.h" 
  177. else
  178. echo shar: Extracting avltree.h \(      3447 characters\) 
  179. sed 's/^X//'<< 'END_OF_avltree.h' > avltree.h
  180. X#ifndef __AVLTREE_H
  181. X#define __AVLTREE_H
  182. X
  183. X/*
  184. X SCCS stuff
  185. X*/
  186. X
  187. X#ifndef SCCS     /* only pick up one SCCS string per module */
  188. X# define SCCS
  189. X# ifndef    lint
  190. X    static char e4d_sccs[] = "@(#)avltree.h  1.2 8/16/94 14:34:18 LMRN";
  191. X#  ifndef COPYRIGHT
  192. X#    define COPYRIGHT
  193. X     static char copyright[] =  "@Copyright (c) 1992 Lomarline " ;
  194. X#  endif
  195. X# endif
  196. X#endif
  197. X/*------------------------------------------------------------------------------
  198. X * Notice:
  199. X * Permission to use, copy, modify, distribute, and sell this software and
  200. X * its documentation for any purpose is hereby granted without fee, provided
  201. X * that the above copyright notices and this permission notice appear in
  202. X * all copies of the software and related documentation.
  203. X * 
  204. X * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  205. X * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  206. X * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  207. X * 
  208. X * IN NO EVENT SHALL LOMARLINE LTD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  209. X * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  210. X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  211. X * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR
  212. X * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  213. X *------------------------------------------------------------------------------
  214. X*/
  215. X
  216. X/*
  217. X* This is modle should complement the standard search.h functions.
  218. X*/
  219. X
  220. X#include  <search.h>
  221. X
  222. X/*------------------------------------------------------------------
  223. X*To relace the standard binary tree unix functions with the avl ones
  224. X*set AVL in the comple line to -DAVL
  225. X*----------------------------------*/
  226. X#ifdef AVL
  227. X#    define tsearch(kp,rpp,cfn) tsearchAVL(kp,rpp,cfn)
  228. X#    define tfind(kp,rpp,cfn)   tfindAVL(kp,rpp,cfn)
  229. X#    define tdelete(kp,rpp,cfn) tdeleteAVL(kp,rpp,cfn)
  230. X#    define twalk(rp,afn)       twalkAVL(rp,afn)
  231. X#endif 
  232. X/*-------------------------------------------------------------------
  233. X* if the std_header <search.h> is included in the module
  234. X* then this VISIT enunerated type will already be defined so
  235. X* watch out for a clash.
  236. X*--------------------*/
  237. X
  238. X
  239. X#ifdef USE_THIS_VISIT
  240. X#undef USE_THIS_VISIT
  241. X#endif
  242. X
  243. X#ifdef __osf__
  244. X#if ! defined ( _SEARCH_H_ ) || ! defined _XOPEN_SOURCE
  245. X#        define USE_THIS_VISIT
  246. X#    endif 
  247. X#endif
  248. X
  249. X
  250. X#ifdef USE_THIS_VISIT
  251. X    typedef enum { preorder, postorder, endorder, leaf } VISIT;
  252. X#endif
  253. X
  254. X/*------------------------------------------------------------------*/
  255. X#if defined( __STDC__ ) && ! defined( NeedFunctionPrototypes )
  256. X#define NeedFunctionPrototypes
  257. X#endif
  258. X
  259. X/*------------------------------------------------------------------*/
  260. X#if defined ( __cplusplus ) && ! defined ( _BEGIN_CPLUSPLUS )
  261. X#    define _BEGIN_CPLUSPLUS extern "C" {
  262. X#    define _END_CPLUSPLUS }
  263. X#endif
  264. X
  265. X_BEGIN_CPLUSPLUS
  266. X
  267. Xextern void    *tsearchAVL(
  268. X#ifdef NeedFunctionPrototypes
  269. X     const void *key,
  270. X     void **rootp,
  271. X     int (*compar)( const void *, const void * )
  272. X#endif
  273. X);
  274. X
  275. Xextern void    *tfindAVL(
  276. X#ifdef NeedFunctionPrototypes
  277. X     const void *key,
  278. X     void **rootp,
  279. X     int (*compar)( const void *, const void * )
  280. X#endif
  281. X);
  282. X
  283. Xextern void    *tdeleteAVL(
  284. X#ifdef NeedFunctionPrototypes
  285. X     const void *key,
  286. X     void **rootp,
  287. X     int (*compar)( const void *, const void * )
  288. X#endif
  289. X);
  290. X
  291. Xextern void twalkAVL(
  292. X#ifdef NeedFunctionPrototypes
  293. X    const void * root,
  294. X    void (*action)(const void *, VISIT, int )
  295. X#endif
  296. X);
  297. X_END_CPLUSPLUS
  298. X
  299. X#endif /* __AVLTREE_H */
  300. END_OF_avltree.h
  301. if test       3447 -ne `wc -c < avltree.h `; then
  302.     echo shar: \"avltree.h\" unpacked with wrong size!       3447 
  303. fi
  304. # end of overwriting check
  305. fi
  306. if test -f avltree.c -a README != "-c" ; then
  307.     echo shar: Will not over-write existing file "avltree.c" 
  308. else
  309. echo shar: Extracting avltree.c \(     24344 characters\) 
  310. sed 's/^X//'<< 'END_OF_avltree.c' > avltree.c
  311. X#ifndef _POSIX_SOURCE
  312. X#   define _POSIX_SOURCE 1
  313. X#endif
  314. X
  315. X/*
  316. X SCCS stuff
  317. X*/
  318. X
  319. X#ifndef SCCS     /* only pick up one SCCS string per module */
  320. X# define SCCS
  321. X# ifndef    lint
  322. X   static char e4d_sccs[] = "@(#)avltree.c    1.2 8/16/94 14:34:18 LMRN";
  323. X#  ifndef COPYRIGHT
  324. X#    define COPYRIGHT
  325. X     static char copyright[] =  "Copyright (c) 1992 Lomarline Ltd " ;
  326. X#  endif
  327. X# endif
  328. X#endif
  329. X
  330. X/*-----------------------------------------------------------------------------
  331. X * Date         : 25 February 1992
  332. X * Version      : 1.2
  333. X * Last Update  : 92/06/06 15:00:50
  334. X * Author       : Lomarline Ltd
  335. X * Compiler(s)  : SunOS 4.1, System V Rel 3, OSF1
  336. X * Module Name  : avltree.c
  337. X * Description  :
  338. X *    Replacement functions to perform tsearch etc, with a AVL balanced tree
  339. X *    structure.  AVL balance is when the height of left and right subtree
  340. X *    from each node differ by one at most.
  341. X *
  342. X * Global Functions:
  343. X *    void *tsearchAVL( void *key, void **rootp, int (*compar)() )
  344. X *    void *tfindAVL( void *key, void **rootp, int (*compar)() )
  345. X *    void *tdeleteAVL( void *key, void **rootp, int (*compar)() )
  346. X *    void twalkAVL( void *root, void (*action)() )
  347. X *
  348. X * Notice:
  349. X * Permission to use, copy, modify, distribute, and sell this software and
  350. X * its documentation for any purpose is hereby granted without fee, provided
  351. X * that the above copyright notices and this permission notice appear in
  352. X * all copies of the software and related documentation.
  353. X * 
  354. X * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  355. X * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  356. X * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  357. X * 
  358. X * IN NO EVENT SHALL LOMARLINE LTD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  359. X * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  360. X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  361. X * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR
  362. X * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  363. X *------------------------------------------------------------------------------
  364. X*/
  365. X
  366. X#define global
  367. X
  368. X#include <stdio.h>
  369. X#include <malloc.h>
  370. X
  371. X#include <search.h>
  372. X#include "avltree.h"
  373. X
  374. X#ifndef TRUE
  375. X#    define TRUE     1
  376. X#    define FALSE 0
  377. X#endif
  378. X
  379. Xstruct Node
  380. X{
  381. X    short        balance;  /* height of left subtree - height of right subtree */
  382. X    void        *info;
  383. X    struct Node    *left;
  384. X    struct Node    *right;
  385. X};
  386. X
  387. X
  388. X/*------------------------------------------------------------------------------
  389. X* Debug and trace info
  390. X *------------------------------------------------------------------------------
  391. X*/
  392. X
  393. X/*
  394. X* If set to zero then All trace is not compiled in
  395. X* The maximum setting at the moment is 300 which will only show entry and exit
  396. X* to txxx functions
  397. X*/
  398. X#define Avl_DEBUG  000
  399. X
  400. X#if !defined ( Avl_DEBUG ) || ( Avl_DEBUG == 0 )
  401. X#    define Avl_Enter(level,name)
  402. X#    define Avl_Trace(level,string)    
  403. X#    define Avl_Return return 
  404. X#else
  405. X/*
  406. X* If you wish to view only one of the txxx functions and it's children then
  407. X* set one of the following
  408. X*/
  409. X#    define Avl_ts (000 * -1)
  410. X#    define Avl_td (000 * -1)
  411. X#    define Avl_tw (000 * -1)
  412. X#    define Avl_tf (000 * -1)
  413. X
  414. X    static long avl_depth ;
  415. X    static long avl_level ;
  416. X
  417. X#    define Avl_Trace(level,string_p)\
  418. X        do\
  419. X        { if(( Avl_DEBUG >= (level) ) && ( avl_fname_p!= NULL))\
  420. X          fprintf(stdout,"Avl_Trace:[%d]%s: %s\n",avl_depth,avl_fname_p,string_p );\
  421. X        }while(0)
  422. X/*
  423. X* NB this must be placed after the initalization of local variables and
  424. X* before the first assignment statment
  425. X*/
  426. X#    define Avl_Enter(level,name_p) \
  427. X        char *avl_fname_p ;{ avl_level = (level) ;avl_fname_p=name_p, \
  428. X        ++avl_depth ; Avl_Trace((level),"Enter"); }
  429. X
  430. X#    define Avl_Return { Avl_Trace(avl_level,"Return"); --avl_depth; } ; return
  431. X
  432. X#endif
  433. X
  434. X
  435. X
  436. X/*------------------------------------------------------------------------------
  437. X * Description:
  438. X *
  439. X *
  440. X * Notes:
  441. X *
  442. X * Parameters:
  443. X *    nodeInfoPtr - Node to locate or insert.
  444. X *    ptr         - Current node in the tree.
  445. X *    rb_flag     - rebalance flag
  446. X *    compar      - Node contents comparison function.
  447. X *
  448. X *
  449. X * 
  450. X * Returns:
  451. X *    NULL        - If node already exists.
  452. X *    otherwise   - Inserted Node.
  453. X *
  454. X *------------------------------------------------------------------------------
  455. X*/
  456. X
  457. X#ifdef NeedFunctionPrototypes
  458. Xstatic void *
  459. Xsearch( 
  460. X    const void            *key,
  461. X    struct Node    **rootp ,
  462. X    int            *rb_flag ,
  463. X    int            (*compar)(const void *, const void *)
  464. X)
  465. X#else
  466. Xstatic void *
  467. Xsearch( key, rootp, rb_flag, compar )
  468. X    void            *key;
  469. X    struct Node    **rootp;
  470. X    int            *rb_flag;
  471. X    int            (*compar)();
  472. X#endif
  473. X{
  474. X    struct Node *p1;
  475. X    struct Node *p2;
  476. X    void            *keyInsert;
  477. X    int            direction;
  478. X
  479. X    Avl_Enter(Avl_ts+300,"search") ;
  480. X
  481. X    if ( *rootp == NULL )
  482. X    {
  483. X        Avl_Trace(Avl_ts+310,"No tree create one");
  484. X
  485. X        if ( (*rootp = (struct Node *)malloc( sizeof( struct Node ) )) != NULL )
  486. X        {
  487. X            *rb_flag        = TRUE;
  488. X            (*rootp)->info    = (void *) key;
  489. X            (*rootp)->left    = NULL;
  490. X            (*rootp)->right   = NULL;
  491. X            (*rootp)->balance = 0;
  492. X            keyInsert         = (void *) &((*rootp)->info);
  493. X        }
  494. X        else
  495. X            keyInsert = NULL;
  496. X        Avl_Return keyInsert;
  497. X    }
  498. X
  499. X    direction = compar( key, (*rootp)->info )  ;
  500. X
  501. X    if ( direction < 0 )
  502. X    {
  503. X        Avl_Trace(Avl_ts+320,"Move left");
  504. X
  505. X        keyInsert = search( key, &((*rootp)->left), rb_flag, compar );
  506. X
  507. X        if ( *rb_flag && (keyInsert != NULL) )
  508. X        {
  509. X            
  510. X            Avl_Trace(Avl_ts+330,"left  branch has grown longer");
  511. X
  512. X            switch( (*rootp)->balance )
  513. X            {
  514. X            case 1: 
  515. X                Avl_Trace(Avl_ts+340,"right branch was longer, now in balance");
  516. X
  517. X                (*rootp)->balance = 0;
  518. X                *rb_flag = FALSE;
  519. X                break;
  520. X
  521. X            case 0:
  522. X                Avl_Trace(Avl_ts+340,
  523. X                    "was in balance, now the left branch is one longer");
  524. X
  525. X                (*rootp)->balance = -1;
  526. X                break;
  527. X
  528. X            case -1:
  529. X                Avl_Trace(Avl_ts+340,"left is to long so rebalance");
  530. X
  531. X                p1 = (*rootp)->left;
  532. X
  533. X                if ( p1->balance < 0 )
  534. X                {
  535. X                    Avl_Trace(Avl_ts+350,"single LL rotation");
  536. X
  537. X                    (*rootp)->left    = p1->right;
  538. X                    p1->right         = *rootp;
  539. X                    (*rootp)->balance = 0;
  540. X                    *rootp            = p1;
  541. X                }
  542. X                else
  543. X                {
  544. X                    Avl_Trace(Avl_ts+350,"double LR rotation");
  545. X
  546. X                    p2                = p1->right;
  547. X                    p1->right         = p2->left;
  548. X                    p2->left          = p1;
  549. X                    (*rootp)->left    = p2->right;
  550. X                    p2->right         = *rootp;
  551. X                    (*rootp)->balance = ( p2->balance < 0 ) ?  1 : 0;
  552. X                    p1->balance       = ( p2->balance > 0 ) ? -1 : 0;
  553. X                    *rootp            = p2 ; 
  554. X                }
  555. X
  556. X                (*rootp)->balance = 0;
  557. X                *rb_flag = FALSE;
  558. X
  559. X                break;
  560. X
  561. X            }    /*    switch    */
  562. X
  563. X        }    /*    if    */
  564. X
  565. X    }
  566. X    else if ( direction > 0 )
  567. X    {
  568. X        Avl_Trace(Avl_ts+320,"Move right");
  569. X
  570. X        keyInsert = search( key, &((*rootp)->right), rb_flag, compar );
  571. X
  572. X        if ( *rb_flag && (keyInsert != NULL) )
  573. X        {
  574. X            Avl_Trace(Avl_ts+330,"right branch has grown longer");
  575. X
  576. X            switch( (*rootp)->balance )
  577. X            {
  578. X            case -1:
  579. X            Avl_Trace(Avl_ts+340,"left branch was longer, now in balance");
  580. X                (*rootp)->balance = 0;
  581. X                *rb_flag = FALSE;
  582. X                break;
  583. X
  584. X            case 0:
  585. X            Avl_Trace(Avl_ts+340,"was in balance, now the right branch is longer");
  586. X                (*rootp)->balance = 1;
  587. X                break;
  588. X
  589. X            case 1:
  590. X            Avl_Trace(Avl_ts+340,"right is to long so rebalance");
  591. X                p1 = (*rootp)->right;
  592. X
  593. X                if ( p1->balance > 0 )
  594. X                {
  595. X                    Avl_Trace(Avl_ts+350,"single RR rotation");
  596. X
  597. X                    (*rootp)->right   = p1->left;
  598. X                    p1->left          = *rootp;
  599. X                    (*rootp)->balance = 0;
  600. X                    *rootp            = p1;
  601. X                }
  602. X                else
  603. X                {
  604. X                    Avl_Trace(Avl_ts+350,"double RL rotation");
  605. X
  606. X                    p2                = p1->left;
  607. X                    p1->left          = p2->right;
  608. X                    p2->right         = p1;
  609. X                    (*rootp)->right   = p2->left;
  610. X                    p2->left          = *rootp;
  611. X                    (*rootp)->balance = ( p2->balance > 0 ) ? -1 : 0;
  612. X                    p1->balance          = ( p2->balance < 0 ) ?  1 : 0;
  613. X                    *rootp            = p2;
  614. X                }
  615. X
  616. X                (*rootp)->balance = 0;
  617. X                *rb_flag = FALSE;
  618. X
  619. X                break;
  620. X            }
  621. X        }    /*    if    */
  622. X    }
  623. X    else
  624. X    {
  625. X        Avl_Trace(Avl_ts+320,"direction == 0, got a match");
  626. X        *rb_flag    = FALSE;
  627. X        keyInsert    = (void *) &((*rootp)->info);
  628. X    }
  629. X
  630. X    Avl_Return keyInsert;
  631. X}
  632. X
  633. X
  634. X/*------------------------------------------------------------------------------
  635. X * Description:
  636. X *    As per tsearch(3).
  637. X *
  638. X * Notes:
  639. X *
  640. X * Parameters:
  641. X *    key         - Node to locate or insert.
  642. X *    rootp       - Tree's root node.
  643. X *    compar      - Node contents comparison function.
  644. X *
  645. X * 
  646. X * Returns:
  647. X *    NULL        - If node already exists.
  648. X *    otherwise   - Inserted Node.
  649. X *
  650. X *------------------------------------------------------------------------------
  651. X*/
  652. X
  653. X#ifdef NeedFunctionPrototypes
  654. Xglobal void    *
  655. XtsearchAVL(
  656. X    const void    *key  ,
  657. X    void    **rootp ,
  658. X    int    (*compar)(const void *, const void *)
  659. X)
  660. X#else
  661. Xglobal void    *
  662. XtsearchAVL( key, rootp, compar )
  663. X    void    *key;
  664. X    void    **rootp;
  665. X    int    (*compar)();
  666. X#endif
  667. X{
  668. X    void * rtn ;
  669. X    int    rb_flag = FALSE;
  670. X
  671. X    Avl_Enter(Avl_ts+200,"tsearchAVL") ;
  672. X
  673. X    rtn = search( key, (struct Node **)rootp, &rb_flag, compar );
  674. X    Avl_Return rtn ;
  675. X}
  676. X
  677. X/*------------------------------------------------------------------------------
  678. X * Description:
  679. X *    As per tfind(3).
  680. X *
  681. X * tfind() searches for an entry in the binary tree, Avl_Returning a pointer to 
  682. X * that entry when a match is found.  However, when key is not matched, 
  683. X * tfind() Avl_Returns a null pointer.
  684. X *
  685. X * Notes:
  686. X *
  687. X * Parameters:
  688. X *    key         - Node to locate.
  689. X *    rootp       - Tree's root node.
  690. X *    compar      - Node contents comparison function.
  691. X *
  692. X * 
  693. X * Returns:
  694. X *    NULL         -
  695. X *    otherwise    -
  696. X *
  697. X *------------------------------------------------------------------------------
  698. X*/
  699. X
  700. X#ifdef NeedFunctionPrototypes
  701. Xglobal void    *
  702. XtfindAVL(
  703. X    const void        *key,
  704. X    void        **rootp,
  705. X    int    (*compar)(const void *, const void *)
  706. X)
  707. X#else
  708. Xglobal void    *
  709. XtfindAVL( key, rootp, compar )
  710. X    void        *key;
  711. X    void        **rootp;
  712. X    int        (*compar)();
  713. X#endif
  714. X{
  715. X    int    direction;
  716. X    void * rtn ;
  717. X
  718. X    Avl_Enter(Avl_tf+200,"tfindAVL") ;
  719. X
  720. X    if ( *rootp == NULL )
  721. X    {
  722. X        Avl_Trace(Avl_tf+210,"rootp is Null");
  723. X        Avl_Return NULL;
  724. X    }
  725. X
  726. X    direction = compar( key, ((struct Node *)(*rootp))->info );
  727. X
  728. X    if ( direction < 0 )
  729. X    {
  730. X        Avl_Trace(Avl_tf+210,"direction < 0, Going left");
  731. X        rtn = tfindAVL( 
  732. X            key, 
  733. X            (void **)&(((struct Node *)(*rootp))->left), 
  734. X            compar );
  735. X    }
  736. X    else if ( direction > 0 )
  737. X    {
  738. X        Avl_Trace(Avl_tf+210,"direction > 0, Going right");
  739. X        rtn = tfindAVL( 
  740. X            key, 
  741. X            (void **)&(((struct Node *)(*rootp))->right), 
  742. X            compar );
  743. X    }
  744. X    else
  745. X    {
  746. X        Avl_Trace(Avl_tf+210,"direction == 0 , Got a match");
  747. X        rtn = &((struct Node *)(*rootp))->info;
  748. X    }
  749. X
  750. X    Avl_Return  rtn ;
  751. X}
  752. X
  753. X
  754. X/*------------------------------------------------------------------------------
  755. X * Description:
  756. X *  Rebalance tree on the left
  757. X *
  758. X *
  759. X * Notes:
  760. X *
  761. X * Parameters:
  762. X *    ptr        -  pointer to (sub) tree ;
  763. X *    rb_flag    -  rebalance flag
  764. X *
  765. X * 
  766. X * Returns:
  767. X *    None
  768. X *
  769. X *------------------------------------------------------------------------------
  770. X*/
  771. X
  772. X#ifdef NeedFunctionPrototypes
  773. Xstatic void
  774. Xbal_left(
  775. X    struct Node    **rootp ,
  776. X    int            *rb_flag 
  777. X)
  778. X#else
  779. Xstatic void
  780. Xbal_left( rootp, rb_flag )
  781. X    struct Node    **rootp;
  782. X    int            *rb_flag;
  783. X#endif
  784. X{
  785. X    struct Node    *p1;
  786. X    struct Node    *p2;
  787. X    int            b1;
  788. X    int            b2;
  789. X
  790. X    Avl_Enter(Avl_td+400,"bal_left") ;
  791. X
  792. X    switch( (*rootp)->balance )
  793. X    {
  794. X    case -1:
  795. X        Avl_Trace(Avl_td+410,"was imbalanced, fixed implicitly");
  796. X        (*rootp)->balance = 0;
  797. X        break;
  798. X
  799. X    case 0:
  800. X        Avl_Trace(Avl_td+410,"was okay, is now one out");
  801. X        (*rootp)->balance = 1;
  802. X        *rb_flag = FALSE;
  803. X        break;
  804. X
  805. X    case 1:
  806. X        Avl_Trace(Avl_td+410,"was alreay one out, so rebalance");
  807. X        p1 = (*rootp)->right;
  808. X        b1 = p1->balance;
  809. X
  810. X        if ( b1 >= 0 )
  811. X        {
  812. X            Avl_Trace(Avl_td+410,"single RR rotation");
  813. X
  814. X            (*rootp)->right    = p1->left;
  815. X            p1->left            = *rootp;
  816. X
  817. X            if ( b1 == 0 )
  818. X            {
  819. X                (*rootp)->balance = 1;
  820. X                p1->balance = -1;
  821. X                *rb_flag = FALSE;
  822. X            }
  823. X            else
  824. X            {
  825. X                (*rootp)->balance = 0;
  826. X                p1->balance = 0;
  827. X            }
  828. X
  829. X            *rootp = p1;
  830. X        }
  831. X        else
  832. X        {
  833. X            Avl_Trace(Avl_td+410,"double RL rotation");
  834. X
  835. X            p2              = p1->left;
  836. X            b2              = p2->balance;
  837. X            p1->left        = p2->right;
  838. X            p2->right       = p1;
  839. X            (*rootp)->right = p2->left;
  840. X            p2->left        = *rootp;
  841. X
  842. X            (*rootp)->balance = ( b2 ==  1 ) ? -1 : 0;
  843. X            p1->balance     = ( b2 == -1 ) ?  1 : 0;
  844. X            *rootp          = p2;
  845. X            p2->balance     = 0;
  846. X        }
  847. X        break;
  848. X
  849. X    }    /*    switch    */
  850. X
  851. X    Avl_Return ;
  852. X}    /*    bal_left    */
  853. X
  854. X
  855. X/*------------------------------------------------------------------------------
  856. X * Description:
  857. X *
  858. X *
  859. X * Notes:
  860. X *
  861. X * Parameters:
  862. X *    rootp        - pointer to (sub) tree 
  863. X *    rb_flag    - repbalnce flag
  864. X *
  865. X * 
  866. X * Returns:
  867. X *    None
  868. X *
  869. X *------------------------------------------------------------------------------
  870. X*/
  871. X
  872. X#ifdef NeedFunctionPrototypes
  873. Xstatic void
  874. Xbal_right(
  875. X    struct Node    **rootp,
  876. X    int            *rb_flag
  877. X)
  878. X#else
  879. Xstatic void
  880. Xbal_right( rootp, rb_flag )
  881. Xstruct Node    **rootp;
  882. Xint            *rb_flag;
  883. X#endif
  884. X{
  885. X    struct Node    *p1;
  886. X    struct Node    *p2;
  887. X    int            b1;
  888. X    int            b2;
  889. X
  890. X    Avl_Enter(Avl_td+400,"bal_right") ;
  891. X
  892. X    switch( (*rootp)->balance )
  893. X    {
  894. X    case 1:
  895. X        Avl_Trace(Avl_td+410,"was imbalanced, fixed implicitly");
  896. X        (*rootp)->balance = 0;
  897. X        break;
  898. X
  899. X    case 0:
  900. X        Avl_Trace(Avl_td+410,"was okay, is now one out");
  901. X        (*rootp)->balance = -1;
  902. X        *rb_flag = FALSE;
  903. X        break;
  904. X
  905. X    case -1:
  906. X        Avl_Trace(Avl_td+410,"was already one out, so rebalance");
  907. X        p1 = (*rootp)->left;
  908. X        b1 = p1->balance;
  909. X
  910. X        if ( b1 <= 0 )
  911. X        {
  912. X            Avl_Trace(Avl_td+410,"single LL rotation");
  913. X
  914. X            (*rootp)->left = p1->right;
  915. X            p1->right = *rootp;
  916. X
  917. X            if ( b1 == 0 )
  918. X            {
  919. X                (*rootp)->balance = -1;
  920. X                p1->balance = 1;
  921. X                *rb_flag = FALSE;
  922. X            }
  923. X            else
  924. X            {
  925. X                (*rootp)->balance = 0;
  926. X                p1->balance = 0;
  927. X            }
  928. X
  929. X            *rootp = p1;
  930. X        }
  931. X        else
  932. X        {
  933. X            Avl_Trace(Avl_td+410,"double LR rotation");
  934. X
  935. X            p2              = p1->right;
  936. X            b2              = p2->balance;
  937. X            p1->right       = p2->left;
  938. X            p2->left        = p1;
  939. X            (*rootp)->left  = p2->right;
  940. X            p2->right       = *rootp;
  941. X
  942. X            (*rootp)->balance = ( b2 == -1 ) ?  1 : 0;
  943. X            p1->balance     = ( b2 ==  1 ) ? -1 : 0;
  944. X            *rootp          = p2;
  945. X            p2->balance     = 0;
  946. X        }
  947. X        break;
  948. X
  949. X    }    /*    switch    */
  950. X
  951. X    Avl_Return ;
  952. X}    /*    bal_right    */
  953. X
  954. X
  955. X/*------------------------------------------------------------------------------
  956. X * Description:
  957. X *  This is called initally from delete but it is recursive.
  958. X *  It is responsible for removing a node when both 
  959. X *  subnodes contain data.
  960. X *
  961. X * Notes:
  962. X *
  963. X * Parameters:
  964. X *    rootp      - Node with two children
  965. X *    q          - 
  966. X *    rb_flag    - rebalanc flag
  967. X *
  968. X * 
  969. X * Returns:
  970. X *    None
  971. X *
  972. X *------------------------------------------------------------------------------
  973. X*/
  974. X
  975. X#ifdef NeedFunctionPrototypes
  976. Xstatic void
  977. Xdel(
  978. X    struct Node    **rootp ,
  979. X    struct Node **q ,
  980. X    int            *rb_flag
  981. X)
  982. X#else
  983. Xstatic void
  984. Xdel( rootp, q, rb_flag )
  985. X    struct Node    **rootp;
  986. X    struct Node **q ;
  987. X    int            *rb_flag;
  988. X#endif
  989. X{
  990. X    Avl_Enter(Avl_td+400,"del") ;
  991. X
  992. X    if ( (*rootp)->right != NULL )
  993. X    {
  994. X        Avl_Trace(Avl_td+410,"Moving right");
  995. X        del( &((*rootp)->right), q , rb_flag );
  996. X
  997. X        if ( *rb_flag )
  998. X        {
  999. X            Avl_Trace(Avl_td+410,"Rebalancing right");
  1000. X            bal_right( rootp, rb_flag );
  1001. X        }
  1002. X    }
  1003. X    else
  1004. X    {
  1005. X        /*
  1006. X         * Delete is only called if both nodes exist
  1007. X         */
  1008. X        Avl_Trace(Avl_td+410,"Moving to the left and repositioning  data");
  1009. X        (*q)->info = (*rootp)->info;
  1010. X        *q = *rootp ;
  1011. X        *rootp = (*rootp)->left;
  1012. X        *rb_flag = TRUE;
  1013. X    }
  1014. X
  1015. X    Avl_Return ;
  1016. X}    /*    del    */
  1017. X
  1018. X
  1019. X/*------------------------------------------------------------------------------
  1020. X * Description:
  1021. X *              Deletes a node form the table and reblances the tree if 
  1022. X *              required.
  1023. X *
  1024. X * Notes:
  1025. X *              It is not realy meaning full to Avl_Return a pointer to the
  1026. X *              parents address but this is done to comply with the UNIX
  1027. X *              man tsearch entrys.
  1028. X *
  1029. X * Parameters:
  1030. X *    key       -
  1031. X *    ptr       - pointer to (sub) tree
  1032. X *    rb_flag   - rebalance flag
  1033. X *    compar    - Node contents comparison function.
  1034. X *
  1035. X * 
  1036. X * Returns:
  1037. X *    parent    - NULL if no matching node found
  1038. X *              or pointer to parent node 
  1039. X *                 if the parentNode parameter is not NUll
  1040. X *              otherwise Avl_Returns a pointer to the deleted nodes information
  1041. X *
  1042. X *------------------------------------------------------------------------------
  1043. X*/
  1044. X
  1045. X#ifdef NeedFunctionPrototypes
  1046. Xstatic void *
  1047. Xdelete( 
  1048. X    const void   *key ,
  1049. X    struct Node **rootp ,
  1050. X    int         *rb_flag ,
  1051. X    int         (*compar)(const void *, const void *),
  1052. X    struct Node **parentNode 
  1053. X)
  1054. X#else
  1055. Xstatic void *
  1056. Xdelete( key, rootp, rb_flag, compar, parentNode )
  1057. X    void        *key;
  1058. X    struct Node **rootp;
  1059. X    int         *rb_flag;
  1060. X    int         (*compar)();
  1061. X    struct Node **parentNode ;
  1062. X#endif
  1063. X{
  1064. X    int    direction;
  1065. X
  1066. X    void   **infoPtr ;
  1067. X
  1068. X    struct Node    *q;
  1069. X
  1070. X    Avl_Enter(Avl_td+300,"delete") ;
  1071. X
  1072. X    if ( *rootp == NULL )
  1073. X    {
  1074. X        Avl_Trace(Avl_td+310,"No node maches key");
  1075. X        *rb_flag = FALSE;
  1076. X        Avl_Return NULL ;
  1077. X    }
  1078. X
  1079. X
  1080. X    direction = compar( key, (*rootp)->info ) ;
  1081. X
  1082. X
  1083. X    if ( direction == 0 )
  1084. X    {
  1085. X        Avl_Trace(Avl_td+310,"We have a match ==  We want to delete this node");
  1086. X        /*
  1087. X         * if parentNode NULL then Avl_Return a pointer to the info 
  1088. X         * else Avl_Return the address of a pointer to the parent node
  1089. X         */
  1090. X        if ( parentNode == NULL )
  1091. X        {
  1092. X            Avl_Trace(Avl_td+330,"Return (deleted node) info");
  1093. X            infoPtr = (*rootp)->info ;
  1094. X        }
  1095. X        else
  1096. X        {
  1097. X            /*
  1098. X             * Then we were at the root node so we will
  1099. X             * have to return a new root node so set it
  1100. X             * to NULL here and test for it in the "if"
  1101. X             * conditions below
  1102. X             */
  1103. X            if ( parentNode == rootp )
  1104. X            {
  1105. X                Avl_Trace(Avl_td+330,"Return infoPtr = rootp");
  1106. X                infoPtr = NULL ;
  1107. X            }
  1108. X            else
  1109. X            {
  1110. X                Avl_Trace(Avl_td+330,"Return infoPtr = parentNode" );
  1111. X                infoPtr = &(*parentNode)->info ;
  1112. X            }
  1113. X        }    
  1114. X                            
  1115. X        q = *rootp;
  1116. X    
  1117. X        if ( q->right == NULL )
  1118. X        {
  1119. X            Avl_Trace(Avl_td+340,
  1120. X            "We have no right node so assign left node to rootp");
  1121. X            *rootp    = q->left;
  1122. X            *rb_flag        = TRUE;
  1123. X            if( q->left == NULL )
  1124. X            {
  1125. X                Avl_Trace(Avl_td+350,"We have no left node either");
  1126. X                    /*infoPtr = NULL ;*/
  1127. X            }
  1128. X            else if ( infoPtr == NULL )
  1129. X                    infoPtr = &(*rootp)->info ;    
  1130. X        }
  1131. X        else if ( q->left == NULL )
  1132. X        {
  1133. X            Avl_Trace(Avl_td+340, 
  1134. X            "We have a right node but no left one so assign rightnode to pointer");
  1135. X
  1136. X            *rootp    = q->right;
  1137. X            *rb_flag        = TRUE;
  1138. X            if ( infoPtr == NULL )
  1139. X                    infoPtr = &(*rootp)->info ;    
  1140. X        }
  1141. X        else
  1142. X        {
  1143. X            Avl_Trace(Avl_td+340,
  1144. X            "We have both nodes but this one must go so delete this one and rebalance");
  1145. X            del( &(q->left),&q, rb_flag );
  1146. X    
  1147. X            if ( *rb_flag )
  1148. X                bal_left( rootp, rb_flag );
  1149. X
  1150. X            if ( infoPtr == NULL )
  1151. X            {
  1152. X                     Avl_Trace(Avl_td+340,
  1153. X                    "PBS We have both nodes infoPtr was NOT NULL");
  1154. X                    infoPtr = &(*rootp)->info ;    
  1155. X            }
  1156. X        }
  1157. X    
  1158. X        free( (void *)q );
  1159. X        q = NULL;
  1160. X    
  1161. X        Avl_Return  infoPtr ; 
  1162. X    }
  1163. X
  1164. X    if( parentNode != NULL )
  1165. X    {
  1166. X        Avl_Trace(Avl_td+320,"Parent node SET to root Node");
  1167. X        parentNode = rootp ;
  1168. X    }    
  1169. X    else
  1170. X    {
  1171. X        Avl_Trace(Avl_td+320,"Parent node NOT set to root Node");
  1172. X    }
  1173. X
  1174. X    if ( direction < 0 )
  1175. X    {
  1176. X        Avl_Trace(Avl_td+350,"key is < node,  Move down the left leaf");
  1177. X
  1178. X        infoPtr = delete( key, &((*rootp)->left), rb_flag, compar, parentNode );
  1179. X
  1180. X        if ( *rb_flag )
  1181. X        {
  1182. X            Avl_Trace(Avl_td+350,"We found our target (direction < 0)");
  1183. X            bal_left( rootp, rb_flag );
  1184. X        }
  1185. X    }
  1186. X    else if ( direction > 0 )
  1187. X    {
  1188. X        Avl_Trace(Avl_td+350,"key is > node, Move down the right leaf");
  1189. X
  1190. X        infoPtr = delete( key, &((*rootp)->right), rb_flag, compar, parentNode );
  1191. X
  1192. X        if ( *rb_flag )
  1193. X        {
  1194. X            Avl_Trace(Avl_td+350,"We found our target (direction < 0)");
  1195. X            bal_right( rootp, rb_flag );
  1196. X        }
  1197. X    }
  1198. X
  1199. X    Avl_Return infoPtr ;
  1200. X}    /*    delete    */
  1201. X
  1202. X
  1203. X/*------------------------------------------------------------------------------
  1204. X * Description:
  1205. X *    As per tdelete(3).
  1206. X * The tdelete() function deletes a node from a binary search tree. Parameters
  1207. X * for this function are used in the same way as for the tsearch() function.
  1208. X * The variable pointed to by the rootp parameter is changed when the deleted
  1209. X * node was the root of the binary tree.  The tdelete() function Avl_Returns a
  1210. X * pointer to the parent of the deleted node, or a null pointer if the node is
  1211. X * not found.
  1212. X *
  1213. X * Notes:
  1214. X *       If this module is compiled with the AVL macro NOT set then
  1215. X *       the value Avl_Returned,(if not NULL), is a pointer to the 
  1216. X *       information stored in the deleted node.
  1217. X *       This will be of more use in most applications because this 
  1218. X *       memory will have to be freed by the calling application.
  1219. X *       Returning the address of the pointer to the parent of the deleted
  1220. X *       node is not of much use in an AVLtree.
  1221. X *
  1222. X * Parameters:
  1223. X *    key - Node to delete.
  1224. X *    rootp       - Tree's root node.
  1225. X *    compar      - Node contents comparison function.
  1226. X *
  1227. X * 
  1228. X * Returns:
  1229. X *    NULL        - If node does not exist .
  1230. X *    otherwise   - AVL == TRUE  a pointer to the deleted nodes parent. 
  1231. X *                               or if the deleted node was root the new root.
  1232. X *    otherwise   - AVL == FALSE a pointer to the information stored in the 
  1233. X *                               deleted node 
  1234. X *
  1235. X *------------------------------------------------------------------------------
  1236. X*/
  1237. X#ifdef NeedFunctionPrototypes
  1238. Xglobal void    *
  1239. XtdeleteAVL(
  1240. X    const void    *key ,
  1241. X    void    **rootp ,
  1242. X    int    (*compar)(const void *, const void *)
  1243. X)
  1244. X#else
  1245. Xglobal void    *
  1246. XtdeleteAVL( key, rootp, compar )
  1247. X    void    *key;
  1248. X    void    **rootp;
  1249. X    int    (*compar)();
  1250. X#endif
  1251. X{
  1252. X    int    rb_flag = FALSE;
  1253. X    void **parentNode ;
  1254. X    void *rtn ;
  1255. X    Avl_Enter(Avl_td+200,"tdeleteAVL") ;
  1256. X
  1257. X#ifdef AVL
  1258. X    parentNode = rootp ;
  1259. X#else
  1260. X    parentNode = NULL ;
  1261. X#endif
  1262. X
  1263. X    rtn = delete( 
  1264. X        key, 
  1265. X        (struct Node **)rootp, 
  1266. X        &rb_flag, 
  1267. X        compar, 
  1268. X        (struct Node **) parentNode
  1269. X        );
  1270. X
  1271. X    Avl_Return rtn ; 
  1272. X
  1273. X}    /*    tdeleteAVL    */
  1274. X
  1275. X/*------------------------------------------------------------------------------
  1276. X * Description:
  1277. X *    Test for a leaf node (node without any children).
  1278. X *
  1279. X * Notes:
  1280. X *
  1281. X * Parameters:
  1282. X *    nodePtr - Node.
  1283. X *
  1284. X * 
  1285. X * Returns:
  1286. X *    0       - If nodePtr points to a non leaf node.
  1287. X *    1       - If nodePtr points to a leaf node.
  1288. X *
  1289. X *------------------------------------------------------------------------------
  1290. X*/
  1291. X
  1292. X#ifdef NeedFunctionPrototypes
  1293. Xstatic int 
  1294. XleafNode( 
  1295. X    struct Node    *nodePtr
  1296. X)
  1297. X#else
  1298. Xstatic int 
  1299. XleafNode( nodePtr )
  1300. X    struct Node    *nodePtr;
  1301. X#endif
  1302. X{
  1303. X    Avl_Enter(Avl_tw+300,"leafNode") ;
  1304. X    Avl_Return (nodePtr->left == NULL) && (nodePtr->right == NULL);
  1305. X}
  1306. X
  1307. X/*------------------------------------------------------------------------------
  1308. X * Description:
  1309. X *    As per twalk(3).
  1310. X *
  1311. X * The twalk() function traverses a binary search tree.  The root parameter
  1312. X * specifies the root of the binary tree to be traversed. Any node in a binary
  1313. X * tree can be used as the root node for a walk below that node.  The action
  1314. X * parameter is the name of a routine to be invoked at each node.  This action
  1315. X * routine is called with three parameters.  The first parameter specifies the
  1316. X * address of the visited node.  The second parameter specifies a value from
  1317. X * an enum data type, which is defined in the search.h include file as fol-
  1318. X * lows:
  1319. X *             typedef enum { preorder, postorder, endorder, leaf } VISIT
  1320. X *
  1321. X * The value of the second parameter in the action routine depends on whether
  1322. X * this is the first (preorder), second (postorder), or third (endorder) time
  1323. X * that the node has been visited during a depth-first, left-to-right traver-
  1324. X * sal of the tree, or whether the node is a leaf.  (A leaf is a node that is
  1325. X * not the parent of another node).  The third parameter in the action routine
  1326. X * is the level of the node in the binary tree with the root being level 0
  1327. X * (zero).
  1328. X *
  1329. X * Notes:
  1330. X *
  1331. X * Parameters:
  1332. X *    root    - Node to use as root for the walk.
  1333. X *    action  - Function to be performed on each node.
  1334. X *
  1335. X * 
  1336. X * Returns:
  1337. X *    None
  1338. X *
  1339. X *-----------------------------------------------------------------------------
  1340. X */
  1341. X
  1342. X#ifdef NeedFunctionPrototypes
  1343. Xglobal void
  1344. XtwalkAVL(
  1345. X    const void        *root ,
  1346. X    void        (*action)(const void *, VISIT, int )
  1347. X)
  1348. X#else
  1349. Xglobal void
  1350. XtwalkAVL( root, action )
  1351. X    void        *root;
  1352. X    void        (*action)();
  1353. X#endif
  1354. X{
  1355. X    static int    level = -1;
  1356. X
  1357. X    Avl_Enter(Avl_tw+200,"twalkAVL") ;
  1358. X
  1359. X    if ( root != NULL )
  1360. X    {
  1361. X        level++;
  1362. X
  1363. X        if ( leafNode( (struct Node *)root ) )
  1364. X        {
  1365. X            action( &((struct Node *)root)->info, leaf, level);
  1366. X        }
  1367. X        else
  1368. X        {
  1369. X            action( &((struct Node *)root)->info, preorder, level);
  1370. X            twalkAVL( (void *)(((struct Node *)root)->left), action );
  1371. X            action( &((struct Node *)root)->info, postorder, level);
  1372. X            twalkAVL( (void *)(((struct Node *)root)->right), action );
  1373. X            action( &((struct Node *)root)->info, endorder, level);
  1374. X        }
  1375. X
  1376. X        level--;
  1377. X    }
  1378. X    else
  1379. X    {
  1380. X        Avl_Trace(Avl_tw+210,"root != NULL");
  1381. X    }
  1382. X    Avl_Return ;
  1383. X}
  1384. END_OF_avltree.c
  1385. if test      24344 -ne `wc -c < avltree.c `; then
  1386.     echo shar: \"avltree.c\" unpacked with wrong size!      24344 
  1387. fi
  1388. # end of overwriting check
  1389. fi
  1390. if test -f atest.c -a README != "-c" ; then
  1391.     echo shar: Will not over-write existing file "atest.c" 
  1392. else
  1393. echo shar: Extracting atest.c \(      4894 characters\) 
  1394. sed 's/^X//'<< 'END_OF_atest.c' > atest.c
  1395. X/*
  1396. X* This program demonstrates that if an original tsearch program is
  1397. X* modified with the inclusion of "avltree.h" and 
  1398. X* both this program and avltree.c are compiled with the AVL flag 
  1399. X* set then the return by tdeletavl() substiitute function is the 
  1400. X* parent just as in the standard functions.
  1401. X*/
  1402. X
  1403. X#include <malloc.h>
  1404. X#include <stdio.h>
  1405. X#include <string.h>
  1406. X#include <search.h>
  1407. X
  1408. X
  1409. X#include <search.h>
  1410. X#include "avltree.h"
  1411. X
  1412. X#define DNUM 0 
  1413. Xtypedef struct Info_s
  1414. X{
  1415. X    int i ;
  1416. X    char name[200] ;
  1417. X}Info_t ;
  1418. X
  1419. XInfo_t info[] =
  1420. X{
  1421. X    { 0,"root"   ,}, { 0,"somebody" ,}, { 0,"nobody"   ,},
  1422. X    { 0,"demon"  ,}, { 0,"fred"     ,}, { 0,"ugand"    ,}, 
  1423. X    { 0,"tokoyo" ,}, { 0,"arthur"   ,}, { 0,"joan"     ,},
  1424. X    { 0,"criss"  ,}, { 0,"larry"    ,}, { 0,"tom"      ,},
  1425. X    { 0,"adam"   ,}, { 0,"eve"      ,}, { 0,"matthias" ,}, 
  1426. X    { 0,"stone"  ,}, { 0,"magic"    ,}, { 0,"trash80"  ,}, 
  1427. X    { 0,"stephen",}, { 0,"madman"   ,}, { 0,"usles"     ,}, 
  1428. X    { 0,"smith"  ,}, { 0,"pullen"   ,}, { 0,"stieger"  ,},
  1429. X    { 0,"crosby" ,}, { 0,"anders"   ,}, { 0,"schmid"   ,},
  1430. X    { 0,"rabbit" ,}, { 0,"steve"    ,}, { 0,"dog"      ,},
  1431. X    { 0,"gassa"  ,}, { 0,"kurtis"   ,}, { 0,"paul"     ,},
  1432. X    { 0,"badone" ,}, { 0,"kevin"    ,}, { 0,"maggi"    ,},
  1433. X    { 0,"roland" ,}, { 0,"casaulta" ,}, { 0,"mad"      ,},
  1434. X    { 0,"" ,}
  1435. X} ;
  1436. X
  1437. X/*----------------------------------------------------------------------
  1438. X*----------------------------------------------------------------------*/
  1439. Xint scmpr(Info_t *key_p, Info_t *info_pp )
  1440. X{
  1441. X    if ( key_p == NULL || info_pp == NULL )
  1442. X    {
  1443. X        fprintf(stdout,"Memory error %d %d \n",key_p, info_pp);
  1444. X        return 0 ;
  1445. X    }
  1446. X#ifdef DEBUG
  1447. X    fprintf(stdout,"kn = %s info = %s\n",key_p->name,info_pp->name);
  1448. X#endif
  1449. X
  1450. X    return strcmp(key_p->name,info_pp->name) ;
  1451. X}
  1452. X
  1453. X/*----------------------------------------------------------------------
  1454. X*----------------------------------------------------------------------*/
  1455. Xint icmpr(Info_t *key_p,Info_t *info_pp )
  1456. X{
  1457. X    if ( key_p == NULL || info_pp == NULL )
  1458. X    {
  1459. X        fprintf(stdout,"Memory error \n");
  1460. X        return 0 ;
  1461. X    }
  1462. X    return info_pp->i - key_p->i ;
  1463. X}
  1464. X
  1465. X/*----------------------------------------------------------------------
  1466. X* This will procude a sorted list when called from twalk
  1467. X*----------------------------------------------------------------------*/
  1468. Xstatic int counter ;
  1469. Xvoid action(Info_t **info_pp, VISIT visit, int level  )
  1470. X{
  1471. X    switch( visit )
  1472. X    {
  1473. X    case  preorder:
  1474. X    break ;
  1475. X    case postorder:
  1476. X
  1477. X        printf("%3d postorder: %d, %2d %s\n",counter++,level,(*info_pp)->i,(*info_pp)->name);
  1478. X
  1479. X    break ;
  1480. X    case endorder:
  1481. X    break ;
  1482. X    case leaf  :
  1483. X        printf("%3d leaf     : %d, %2d %s\n",counter++,level,(*info_pp)->i,(*info_pp)->name);
  1484. X    break ;
  1485. X    default :
  1486. X        printf("%3d default  : %d, %2d %s\n",counter++,level,(*info_pp)->i,(*info_pp)->name);
  1487. X    break ;
  1488. X    }
  1489. X
  1490. X    return ;
  1491. X}
  1492. X
  1493. X/*----------------------------------------------------------------------
  1494. X*----------------------------------------------------------------------*/
  1495. Xmain()
  1496. X{
  1497. X
  1498. X    int i ;
  1499. X    int numOfElements ;
  1500. X    Info_t **info_pp ;
  1501. X    Info_t *tree ;
  1502. X    tree = NULL ;
  1503. X    
  1504. X#ifdef AVL
  1505. X    printf("AVL IS SET\n");
  1506. X#else
  1507. X    printf("AVL is NOT set\n");
  1508. X#endif
  1509. X    for( i = 0 ; info[i].name[0] != 0 ; i++)
  1510. X        info[i].i = i ;
  1511. X
  1512. X    numOfElements = i ;
  1513. X
  1514. X    for( i = 0 ; i  < numOfElements ; i++ )
  1515. X    {
  1516. X        info_pp = (Info_t **) tsearch(&info[i], &tree, scmpr ) ;
  1517. X        printf("tsearch %2d %10s\n", (*info_pp)->i , (*info_pp)->name);
  1518. X    }
  1519. X
  1520. X    printf("\nSorted data ---------------------------------------------------\n");
  1521. X    twalk( tree, action ) ;
  1522. X
  1523. X    printf("\ncheck that all elements are in the tree ------------------------\n");
  1524. X    for ( i = 0 ; i < numOfElements ; i ++ )
  1525. X    {
  1526. X        info_pp = (Info_t **) tfind(&info[i],&tree,scmpr );
  1527. X
  1528. X        if( info_pp == NULL )
  1529. X            printf(" Not found %2d %10s,", info[i].i, info[i].name);
  1530. X        else
  1531. X            printf("     FOUND %2d %10s,", (*info_pp)->i , (*info_pp)->name);
  1532. X        if ( i%3 == 2 )
  1533. X        printf("\n");
  1534. X    }
  1535. X    printf("\n");
  1536. X
  1537. X
  1538. X    printf("deleteing[%d]   %2d %10s\n\n",DNUM, info[DNUM].i, info[DNUM].name);
  1539. X
  1540. X    info_pp = (Info_t **) tdelete(&info[DNUM],&tree, scmpr ) ;
  1541. X
  1542. X#ifdef AVL
  1543. X    printf("\nAVL is set so avltree should return the parent as standard\n");
  1544. X#else
  1545. X    printf("\nAVL not set so using libray calls tsearch() etc\n");
  1546. X#endif
  1547. X    printf("parent %2d %10s\n\n", (*info_pp)->i , (*info_pp)->name);
  1548. X
  1549. X    printf("\ncheck only one data item has been removed ----------------------\n");
  1550. X    for ( i = 0 ; i < numOfElements ; i ++ )
  1551. X    {
  1552. X        info_pp = (Info_t **) tfind(&info[i],&tree ,scmpr );
  1553. X
  1554. X        if( info_pp == NULL )
  1555. X            printf(" Not found %2d %10s,", info[i].i, info[i].name);
  1556. X        else
  1557. X            printf("     FOUND %2d %10s,", (*info_pp)->i , (*info_pp)->name);
  1558. X        if ( i%3 == 2 )
  1559. X        printf("\n");
  1560. X    }
  1561. X        printf("\n");
  1562. X
  1563. X    printf("Test that data alreay deleted returns a NULL\n");
  1564. X    info_pp = (Info_t **) tdelete(&info[DNUM],&tree, scmpr ) ;
  1565. X    printf("past tdeleteAVL\n");
  1566. X    if ( info_pp != NULL )
  1567. X        printf("[%d] not deleted\t%d >%s<\n\n",
  1568. X            DNUM,(*info_pp)->i, (*info_pp)->name);
  1569. X    else
  1570. X        printf("This is corredt, NULL returned\n\n");
  1571. X}
  1572. END_OF_atest.c
  1573. if test       4894 -ne `wc -c < atest.c `; then
  1574.     echo shar: \"atest.c\" unpacked with wrong size!       4894 
  1575. fi
  1576. # end of overwriting check
  1577. fi
  1578. if test -f btest.c -a README != "-c" ; then
  1579.     echo shar: Will not over-write existing file "btest.c" 
  1580. else
  1581. echo shar: Extracting btest.c \(      5531 characters\) 
  1582. sed 's/^X//'<< 'END_OF_btest.c' > btest.c
  1583. X/*
  1584. X* this program shows that it the modules are compiled witout the
  1585. X* AVL flag set that the return on tdeleteAVL is the data in the deleted node
  1586. X* so that it can "destructed by an application function
  1587. X*/
  1588. X
  1589. X#include <malloc.h>
  1590. X#include <stdio.h>
  1591. X#include <string.h>
  1592. X#include <search.h>
  1593. X
  1594. X
  1595. X#include <search.h>
  1596. X#include "avltree.h"
  1597. X
  1598. X#define DNUM 4
  1599. X
  1600. Xtypedef struct Info_s
  1601. X{
  1602. X    int i ;
  1603. X    char name[200] ;
  1604. X}Info_t ;
  1605. X
  1606. XInfo_t info[] =
  1607. X{
  1608. X    { 0,"root"   ,}, { 0,"somebody" ,}, { 0,"nobody"   ,},
  1609. X    { 0,"demon"  ,}, { 0,"fred"     ,}, { 0,"ugand"    ,}, 
  1610. X    { 0,"tokoyo" ,}, { 0,"arthur"   ,}, { 0,"joan"     ,},
  1611. X    { 0,"criss"  ,}, { 0,"larry"    ,}, { 0,"tom"      ,},
  1612. X    { 0,"adam"   ,}, { 0,"eve"      ,}, { 0,"matthias" ,}, 
  1613. X    { 0,"stone"  ,}, { 0,"magic"    ,}, { 0,"trash80"  ,}, 
  1614. X    { 0,"stephen",}, { 0,"madman"   ,}, { 0,"usles"     ,}, 
  1615. X    { 0,"smith"  ,}, { 0,"pullen"   ,}, { 0,"stieger"  ,},
  1616. X    { 0,"crosby" ,}, { 0,"anders"   ,}, { 0,"schmid"   ,},
  1617. X    { 0,"rabbit" ,}, { 0,"steve"    ,}, { 0,"dog"      ,},
  1618. X    { 0,"gassa"  ,}, { 0,"kurtis"   ,}, { 0,"paul"     ,},
  1619. X    { 0,"badone" ,}, { 0,"kevin"    ,}, { 0,"maggi"    ,},
  1620. X    { 0,"roland" ,}, { 0,"casaulta" ,}, { 0,"mad"      ,},
  1621. X    { 0,"" ,}
  1622. X} ;
  1623. X
  1624. X/*----------------------------------------------------------------------
  1625. X*----------------------------------------------------------------------*/
  1626. Xint scmpr(Info_t *key_p, Info_t *info_pp )
  1627. X{
  1628. X    if ( key_p == NULL || info_pp == NULL )
  1629. X    {
  1630. X        fprintf(stdout,"Memory error %d %d \n",key_p, info_pp);
  1631. X        return 0 ;
  1632. X    }
  1633. X#ifdef DEBUG
  1634. X    fprintf(stdout,"kn = %s info = %s\n",key_p->name,info_pp->name);
  1635. X#endif
  1636. X
  1637. X    return strcmp(key_p->name,info_pp->name) ;
  1638. X}
  1639. X
  1640. X/*----------------------------------------------------------------------
  1641. X*----------------------------------------------------------------------*/
  1642. Xint icmpr(Info_t *key_p,Info_t *info_pp )
  1643. X{
  1644. X    if ( key_p == NULL || info_pp == NULL )
  1645. X    {
  1646. X        fprintf(stdout,"Memory error \n");
  1647. X        return 0 ;
  1648. X    }
  1649. X    return info_pp->i - key_p->i ;
  1650. X}
  1651. X
  1652. X/*----------------------------------------------------------------------
  1653. X* This will procude a sorted list when called from twalkAVL
  1654. X*----------------------------------------------------------------------*/
  1655. Xstatic int counter ;
  1656. Xvoid action(Info_t **info_pp, VISIT visit, int level  )
  1657. X{
  1658. X    switch( visit )
  1659. X    {
  1660. X    case  preorder:
  1661. X    break ;
  1662. X    case postorder:
  1663. X        printf("%3d postorder: %d, %2d %s\n",
  1664. X            counter++,level,(*info_pp)->i,(*info_pp)->name);
  1665. X
  1666. X    break ;
  1667. X    case endorder:
  1668. X    break ;
  1669. X    case leaf  :
  1670. X        printf("%3d leaf     : %d, %2d %s\n",
  1671. X            counter++,level,(*info_pp)->i,(*info_pp)->name);
  1672. X    break ;
  1673. X    default :
  1674. X        printf("%3d default  : %d, %2d %s\n",
  1675. X            counter++,level,(*info_pp)->i,(*info_pp)->name);
  1676. X    break ;
  1677. X    }
  1678. X
  1679. X    return ;
  1680. X}
  1681. X
  1682. X/*----------------------------------------------------------------------
  1683. X*----------------------------------------------------------------------*/
  1684. Xmain()
  1685. X{
  1686. X
  1687. X    int i ;
  1688. X    int j ;
  1689. X    int numOfElements ;
  1690. X    Info_t **info_pp ;
  1691. X    Info_t *info_p ;
  1692. X    Info_t *tree ;
  1693. X    tree = NULL ;
  1694. X    
  1695. X#ifdef AVL
  1696. X    printf("AVL IS SET\n");
  1697. X#else
  1698. X    printf("AVL is NOT set\n");
  1699. X#endif
  1700. X
  1701. X    for( i = 0 ; info[i].name[0] != 0 ; i++)
  1702. X        info[i].i = i ;
  1703. X
  1704. X    numOfElements = i ;
  1705. X
  1706. X    /*
  1707. X     * add an index number to each element
  1708. X     */
  1709. X    for( i = 0 ; i  < numOfElements ; i++ )
  1710. X    {
  1711. X        info_pp = (Info_t **) tsearchAVL(&info[i], &tree, scmpr ) ;
  1712. X        printf("tsearchAVL %2d %10s\n", (*info_pp)->i, (*info_pp)->name);
  1713. X    }
  1714. X
  1715. X    twalkAVL( tree, action ) ;
  1716. X
  1717. X    /*
  1718. X     * check that all elements are in the tree
  1719. X     */
  1720. X    for ( i = 0 ; i < numOfElements ; i ++ )
  1721. X    {
  1722. X        info_pp = (Info_t **) tfindAVL(&info[i],&tree,scmpr );
  1723. X
  1724. X        if( info_pp == NULL )
  1725. X            printf(" Not found %2d %10s,", info[i].i, info[i].name);
  1726. X        else
  1727. X            printf("     FOUND %2d %10s,", (*info_pp)->i, (*info_pp)->name);
  1728. X
  1729. X        if ( i%3 == 2 )
  1730. X            printf("\n");    
  1731. X    }
  1732. X    printf("\n");
  1733. X
  1734. X    /*
  1735. X     * remove all elements from the AVL tree
  1736. X     */
  1737. X    for (  j = 0 ; j < numOfElements ; j ++ )
  1738. X    {
  1739. X        printf("Before Delete -------------------------\n");
  1740. X        printf("[%2d] target\t%2d %10s\n", j, info[j].i, info[j].name);
  1741. X
  1742. X#ifdef AVL
  1743. X        info_pp = (Info_t **) tdeleteAVL(&info[j],&tree, scmpr ) ;
  1744. X        if ( info_pp != NULL )
  1745. X            printf("[%2d] parent\t%2d %10s\n\n",j,(*info_pp)->i,(*info_pp)->name);
  1746. X#else
  1747. X        info_p = (Info_t *) tdeleteAVL(&info[j],&tree, scmpr ) ;
  1748. X        if ( info_p != NULL )
  1749. X            printf("[%2d] deleted\t%2d %10s\n\n",j,info_p->i, info_p->name);
  1750. X        /*
  1751. X         * Can't be freed bacause a fixed array
  1752. X         *if( info_p != NULL )
  1753. X         *    free(info_p);
  1754. X         */
  1755. X#endif
  1756. X
  1757. X        /*
  1758. X         * Check that the elements have been removed
  1759. X         */
  1760. X
  1761. X        for ( i = 0 ; i < numOfElements ; i ++ )
  1762. X        {
  1763. X            info_pp = (Info_t **) tfindAVL(&info[i],&tree ,scmpr );
  1764. X    
  1765. X            if( info_pp == NULL )
  1766. X                printf(" Not found %2d %10s,", info[i].i, info[i].name);
  1767. X            else
  1768. X                printf("     FOUND %2d %10s,", (*info_pp)->i, (*info_pp)->name);
  1769. X
  1770. X            if ( i%3 == 2 )
  1771. X                printf("\n");    
  1772. X        }
  1773. X        printf("\n");
  1774. X        printf("After Delete -------------------------\n");
  1775. X    }
  1776. X
  1777. X/*------------------------------------------------------------------*/
  1778. X    printf("Test that data alreay deleted returns a NULL\n");
  1779. X#ifdef AVL
  1780. X    info_p = (Info_t *) tdeleteAVL(&info[DNUM],&tree, scmpr ) ;
  1781. X    info_pp = &info_p ;
  1782. X    if ( info_p != NULL )
  1783. X#else
  1784. X    info_pp = (Info_t **)  tdeleteAVL(&info[DNUM],&tree, scmpr ) ;
  1785. X    if ( info_pp != NULL )
  1786. X#endif
  1787. X        printf("[%d] deleted\t%d >%s<\n\n",
  1788. X            DNUM, (*info_pp)->i, (*info_pp)->name);
  1789. X    else
  1790. X        printf("This is corredt, NULL returned\n\n");
  1791. X
  1792. X
  1793. X    printf("Before -------------------------------------------------------\n");
  1794. X    printf("twalkAVL tree_p == %d\n",(long) tree);
  1795. X    twalkAVL( tree, action ) ;
  1796. X    printf("After --------------------------------------------------------\n");
  1797. X}
  1798. END_OF_btest.c
  1799. if test       5531 -ne `wc -c < btest.c `; then
  1800.     echo shar: \"btest.c\" unpacked with wrong size!       5531 
  1801. fi
  1802. # end of overwriting check
  1803. fi
  1804. if test -f makefile -a README != "-c" ; then
  1805.     echo shar: Will not over-write existing file "makefile" 
  1806. else
  1807. echo shar: Extracting makefile \(       961 characters\) 
  1808. sed 's/^X//'<< 'END_OF_makefile' > makefile
  1809. X#####################################################################
  1810. X#
  1811. X# The makefile for the AVLtree software
  1812. X#
  1813. X# atest    == standard tsearch program with stdlib
  1814. X# atestavl == standard tsearch program with avltree.o
  1815. X# 
  1816. X# btest    == test without AVL flag set, returns deleteed node info
  1817. X# btestavl == test with AVL flag set,  returns pointer to parent node
  1818. X#####################################################################
  1819. X
  1820. XCFLAGS=-g 
  1821. XDFLAGS=-DAVL
  1822. X
  1823. Xall: atest atestavl btest btestavl
  1824. X
  1825. X
  1826. Xatest: atest.c
  1827. X     cc atest.c -o atest $(CFLAGS)
  1828. X
  1829. Xatestavl: avltree.o atest.c
  1830. X     cc atest.c -o atestavl $(CFLAGS) $(DFLAGS)  avltree.o
  1831. X
  1832. X
  1833. Xbtest: tree.o btest.c
  1834. X    cc btest.c -o btest $(CFLAGS) tree.o
  1835. X
  1836. Xbtestavl: avltree.o btest.c
  1837. X    cc btest.c -o btestavl $(CFLAGS) $(DFLAGS) avltree.o
  1838. X
  1839. X
  1840. Xavltree.o: avltree.c makefile
  1841. X    cc avltree.c -c $(CFLAGS) $(DFLAGS)
  1842. X
  1843. Xtree.o: avltree.c makefile
  1844. X    cc -o tree.o avltree.c -c $(CFLAGS)
  1845. X
  1846. X
  1847. X
  1848. Xclean:
  1849. X    rm -f *.o atest atestavl btest btestavl core 
  1850. END_OF_makefile
  1851. if test        961 -ne `wc -c < makefile `; then
  1852.     echo shar: \"makefile\" unpacked with wrong size!        961 
  1853. fi
  1854. # end of overwriting check
  1855. fi
  1856. echo shar: End of shell archive.
  1857.