home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / programm / 2512 < prev    next >
Encoding:
Internet Message Format  |  1992-08-27  |  21.6 KB

  1. Path: sparky!uunet!uunet!not-for-mail
  2. From: avg@rodan.UU.NET (Vadim Antonov)
  3. Newsgroups: comp.programming
  4. Subject: Re: Why Are Red-Black Trees Obscure?
  5. Date: 27 Aug 1992 16:45:49 -0400
  6. Organization: Berkeley Software Design
  7. Lines: 1012
  8. Message-ID: <17jettINNpru@rodan.UU.NET>
  9. References: <1992Aug27.115551.7958@daimi.aau.dk> <PSU.92Aug27104235@ptero.cs.duke.edu> <BtnG7n.2o1@ais.org>
  10. NNTP-Posting-Host: rodan.uu.net
  11.  
  12. They aren't.
  13.  
  14. --vadim
  15.  
  16. # This is a shell archive.  Save it in a file, remove anything before
  17. # this line, and then unpack it by entering "sh file".  Note, it may
  18. # create directories; files and directories will be owned by you and
  19. # have default permissions.
  20. #
  21. # This archive contains:
  22. #
  23. #    rb-generic.c
  24. #    rb-test.c
  25. #
  26. echo x - rb-generic.c
  27. sed 's/^X//' >rb-generic.c << 'END-of-rb-generic.c'
  28. X/*
  29. X * Copyright 1991, Vadim Antonov
  30. X * All rights reserved.
  31. X *
  32. X * This code is developed as a part of Grail project and can
  33. X * be used and redistributed freely as long as this copyright
  34. X * notice is retained.
  35. X *
  36. X * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES.
  37. X */
  38. X
  39. X/* Revision 1.0, 7-12-1991 */
  40. X
  41. X/*
  42. X * Generic simple/interval red-black tree maintenance routines
  43. X *
  44. X *
  45. X *    This file should be included into C source files after the
  46. X *    following defines:
  47. X *
  48. X *    RB_INTERVALS        - interval trees
  49. X *    RB_MAY_OVERLAP        - intervals may overlap
  50. X *    RB_MINIMAL_KEY        - the minimal value of a key
  51. X *    RB_NODE_REF_TYPE    - type of a pointer to a tree node
  52. X *    RB_KEY_TYPE        - type of the key (or interval limits)
  53. X *    RB_LESS(a, b)         - true if a < b
  54. X *    RB_EQ(a, b)        - true if a == b
  55. X *    RB_ISRED(node)        - check if RED flag is set for node
  56. X *    RB_SETRED(node)        - set the node red
  57. X *    RB_SETBLACK(node)    - set the node black
  58. X *    RB_NOINLINE        - do not do inlines
  59. X *    RB_DEBUG        - add routines for validating and printing
  60. X *                  out the tree
  61. X *    RB_KEY_FMT        - format (like "%d") for printing the value of
  62. X *                  a key
  63. X *    RB_XPRINTF(x)        - if defined - a statement printing additional
  64. X *                  information from the tree node x. Should not
  65. X *                  print newline at the end.
  66. X *
  67. X *     This file defines the following routines (xxx is for RB_PROC_PREFIX):
  68. X *
  69. X *    RB_SEARCH        node = search(tree, key)  or
  70. X *                node = search(tree, b, e) for interval trees
  71. X *    RB_OVERLAP        node = overlap(tree, b, e)
  72. X *    RB_INSERT        insert(tree, node)
  73. X *    RB_DELETE        delete(tree, node)
  74. X *    RB_INITIALIZE        initialize(tree)
  75. X *    RB_PRINT        print(tree)
  76. X *    RB_SCAN1        scan1(tree)
  77. X *    RB_SCAN2        scan2(tree)
  78. X *    RB_SCAN3        scan3(tree)
  79. X *
  80. X * Routines scanning the tree can be created with the defines RB_SCANn
  81. X * (the name for the scan routine) and RB_SCAN_PROCn(x) where n = 1,2 or 3 and
  82. X * x is the pointer to the current node. RB_SCANn_ORDERED should be defined if
  83. X * scanning nodes in increasing order is desired; but this mode does not allow
  84. X * for destruction of nodes.
  85. X *
  86. X *    The structure *RB_NODE_REF_TYPE should contain the following fields
  87. X *    (yyy is for RB_FIELD_PREFIX):
  88. X *
  89. X * RB_KEY_TYPE:
  90. X *    RB_BEGIN    - the beginning of the interval (for interval trees)
  91. X *              or the key (for non-interval trees)
  92. X *    RB_END        - the end of the interval (for interval trees)
  93. X *    RB_MAX        - the last point of all intervals in the subtree 
  94. X *              (interval trees only)
  95. X *
  96. X * RB_NODE_REF_TYPE:
  97. X *    RB_LEFT        - link to the left
  98. X *     RB_RIGHT    - link to the right
  99. X *    RB_PARENT    - link to the parent
  100. X *
  101. X * The following definitions should contain some unique names for internal procedures:
  102. X *    RB_MAX3_
  103. X *    RB_ROTATE_LEFT_
  104. X *    RB_ROTATE_RIGHT_
  105. X *    RB_PRINT_
  106. X */
  107. X
  108. X
  109. X#ifdef RB_SCAN1
  110. X/*
  111. X * Scan the tree from lower nodes to upper (can be used to
  112. X * destroy the whole tree if non-ordered)
  113. X */
  114. Xvoid RB_SCAN1(tt)
  115. X    register RB_NODE_REF_TYPE tt;
  116. X{
  117. X    register RB_NODE_REF_TYPE x = tt->RB_LEFT;
  118. X    register RB_NODE_REF_TYPE z;
  119. X
  120. X    for(;;) {
  121. X        while( x->RB_LEFT != tt )
  122. X            x = x->RB_LEFT;
  123. X        for(;;) {
  124. X#ifdef RB_SCAN1_ORDERED
  125. X            RB_SCAN_PROC1(x);
  126. X#endif
  127. X            if( x->RB_RIGHT != tt ) {
  128. X                x = x->RB_RIGHT;
  129. X                break;
  130. X            }
  131. X        
  132. X            for(;;) {
  133. X                z = x->RB_PARENT;
  134. X#ifndef RB_SCAN1_ORDERED
  135. X                RB_SCAN_PROC1(x);
  136. X#endif
  137. X                if( x == z->RB_LEFT ) {
  138. X                    if( z == tt )
  139. X                        return;
  140. X                    x = z;
  141. X                    break;
  142. X                }
  143. X                x = z;
  144. X            }
  145. X        }
  146. X    }
  147. X}
  148. X#endif /* RB_SCAN1 */
  149. X
  150. X/* 2nd replica */
  151. X#ifdef RB_SCAN2
  152. Xvoid RB_SCAN2(tt)
  153. X    register RB_NODE_REF_TYPE tt;
  154. X{
  155. X    register RB_NODE_REF_TYPE x = tt->RB_LEFT;
  156. X    register RB_NODE_REF_TYPE z;
  157. X
  158. X    for(;;) {
  159. X        while( x->RB_LEFT != tt )
  160. X            x = x->RB_LEFT;
  161. X        for(;;) {
  162. X#ifdef RB_SCAN2_ORDERED
  163. X            RB_SCAN_PROC2(x);
  164. X#endif
  165. X            if( x->RB_RIGHT != tt ) {
  166. X                x = x->RB_RIGHT;
  167. X                break;
  168. X            }
  169. X        
  170. X            for(;;) {
  171. X                z = x->RB_PARENT;
  172. X#ifndef RB_SCAN2_ORDERED
  173. X                RB_SCAN_PROC2(x);
  174. X#endif
  175. X                if( x == z->RB_LEFT ) {
  176. X                    if( z == tt )
  177. X                        return;
  178. X                    x = z;
  179. X                    break;
  180. X                }
  181. X                x = z;
  182. X            }
  183. X        }
  184. X    }
  185. X}
  186. X#endif /* RB_SCAN2 */
  187. X
  188. X/* 3rd replica */
  189. X#ifdef RB_SCAN3
  190. Xvoid RB_SCAN3(tt)
  191. X    register RB_NODE_REF_TYPE tt;
  192. X{
  193. X    register RB_NODE_REF_TYPE x = tt->RB_LEFT;
  194. X    register RB_NODE_REF_TYPE z;
  195. X
  196. X    for(;;) {
  197. X        while( x->RB_LEFT != tt )
  198. X            x = x->RB_LEFT;
  199. X        for(;;) {
  200. X#ifdef RB_SCAN3_ORDERED
  201. X            RB_SCAN_PROC3(x);
  202. X#endif
  203. X            if( x->RB_RIGHT != tt ) {
  204. X                x = x->RB_RIGHT;
  205. X                break;
  206. X            }
  207. X        
  208. X            for(;;) {
  209. X                z = x->RB_PARENT;
  210. X#ifndef RB_SCAN3_ORDERED
  211. X                RB_SCAN_PROC3(x);
  212. X#endif
  213. X                if( x == z->RB_LEFT ) {
  214. X                    if( z == tt )
  215. X                        return;
  216. X                    x = z;
  217. X                    break;
  218. X                }
  219. X                x = z;
  220. X            }
  221. X        }
  222. X    }
  223. X}
  224. X#endif /* RB_SCAN3 */
  225. X
  226. X#ifndef RB_INTERVALS
  227. X
  228. X#ifdef RB_SEARCH
  229. X/*
  230. X * Search for the key
  231. X */
  232. XRB_NODE_REF_TYPE RB_SEARCH(tt, key)
  233. X    register RB_NODE_REF_TYPE tt;
  234. X    register RB_KEY_TYPE      key;
  235. X{
  236. X    register RB_NODE_REF_TYPE t = tt->RB_LEFT;
  237. X
  238. X    while( t != tt ) {
  239. X        if( RB_EQ(t->RB_BEGIN, key) )
  240. X            return t;
  241. X        t = (RB_LESS(key, t->RB_BEGIN)) ? t->RB_LEFT : t->RB_RIGHT;
  242. X    }
  243. X    return 0;
  244. X}
  245. X#endif /* RB_SEARCH */
  246. X
  247. X/* for any case... */
  248. X#undef RB_MAY_OVERLAP
  249. X#undef RB_OVERLAP
  250. X
  251. X#else    /* RB_INTERVALS */
  252. X
  253. X
  254. X#ifdef RB_MAY_OVERLAP
  255. X
  256. X#ifdef RB_SEARCH
  257. X/*
  258. X * Search in the interval red-black tree for
  259. X * exact matches (the tree can keep overlapping intervals)
  260. X */
  261. XRB_NODE_REF_TYPE RB_SEARCH(tt, b, e)
  262. X    register RB_NODE_REF_TYPE tt;
  263. X    register RB_KEY_TYPE b;
  264. X    register RB_KEY_TYPE e;
  265. X{
  266. X    register RB_NODE_REF_TYPE t = tt->RB_LEFT;
  267. X
  268. X    while( t != tt ) {
  269. X        if( RB_EQ(b, t->RB_BEGIN) ) {
  270. X            if( RB_EQ(t->RB_END, e) )
  271. X                return t;
  272. X            t = (RB_LESS(e, t->RB_END)) ? t->RB_LEFT : t->RB_RIGHT;
  273. X        } else
  274. X            t = (RB_LESS(b, t->RB_BEGIN)) ? t->RB_LEFT : t->RB_RIGHT;
  275. X    }
  276. X    return 0;
  277. X}
  278. X#endif /* RB_SEARCH */
  279. X
  280. X
  281. X#ifdef RB_OVERLAP
  282. X/*
  283. X * Search for an overlapping interval in red-black tree
  284. X *    (tree can keep overlapping intervals)
  285. X */
  286. XRB_NODE_REF_TYPE RB_OVERLAP(tt, b, e)
  287. X    register RB_NODE_REF_TYPE tt;
  288. X    register RB_KEY_TYPE b;
  289. X    register RB_KEY_TYPE e;
  290. X{
  291. X    register RB_NODE_REF_TYPE t = tt->RB_LEFT;
  292. X    register RB_NODE_REF_TYPE x;
  293. X
  294. X    while( t != tt ) {
  295. X        if( !(RB_LESS(t->RB_END, b)) && !(RB_LESS(e, t->RB_BEGIN)) )
  296. X            return t;
  297. X        x = t->RB_RIGHT;
  298. X        t = t->RB_LEFT;
  299. X        if( t == tt || (RB_LESS(t->RB_MAX, b)) ) 
  300. X            t = x;
  301. X    }
  302. X    return 0;
  303. X}
  304. X#endif
  305. X
  306. X/*
  307. X * Calculate maximum of 3 values
  308. X */
  309. X#ifndef RB_NOINLINE
  310. Xinline
  311. X#endif
  312. Xstatic RB_KEY_TYPE RB_MAX3_(x)
  313. X    register RB_NODE_REF_TYPE x;
  314. X{
  315. X    register RB_KEY_TYPE a = x->RB_LEFT->RB_MAX;
  316. X
  317. X    if( RB_LESS(a, x->RB_RIGHT->RB_MAX) )
  318. X        a = x->RB_RIGHT->RB_MAX;
  319. X    if( RB_LESS(a, x->RB_END) )
  320. X        a = x->RB_END;
  321. X    return a;
  322. X}
  323. X
  324. X#else /* !RB_MAY_OVERLAP */
  325. X
  326. X#ifdef RB_SEARCH
  327. X/*
  328. X * Search in the interval red-black tree for
  329. X * exact matches (tree does not keep overlapping intervals)
  330. X */
  331. XRB_NODE_REF_TYPE RB_SEARCH(tt, b, e)
  332. X    register RB_NODE_REF_TYPE tt;
  333. X    register RB_KEY_TYPE b;
  334. X    register RB_KEY_TYPE e;
  335. X{
  336. X    register RB_NODE_REF_TYPE t = tt->RB_LEFT;
  337. X
  338. X    while( t != tt ) {
  339. X        if( RB_EQ(b, t->RB_BEGIN) ) {
  340. X            if( RB_EQ(t->RB_END, e) )
  341. X                return t;
  342. X            return 0;
  343. X        }
  344. X        t = (RB_LESS(b, t->RB_BEGIN)) ? t->RB_LEFT : t->RB_RIGHT;
  345. X    }
  346. X    return 0;
  347. X}
  348. X#endif /* RB_SEARCH */
  349. X
  350. X#ifdef RB_OVERLAP
  351. X/*
  352. X * Search for an overlapping interval in red-black tree
  353. X *    (tree does not keep overlapping intervals)
  354. X */
  355. XRB_NODE_REF_TYPE RB_OVERLAP(tt, b, e)
  356. X    register RB_NODE_REF_TYPE tt;
  357. X    register RB_KEY_TYPE b;
  358. X    register RB_KEY_TYPE e;
  359. X{
  360. X    register RB_NODE_REF_TYPE t = tt->RB_LEFT;
  361. X
  362. X    while( t != tt ) {
  363. X        if( !(RB_LESS(t->RB_END, b)) && !(RB_LESS(e, t->RB_BEGIN)) )
  364. X            return t;
  365. X        t = (RB_LESS(b, t->RB_BEGIN)) ? t->RB_LEFT : t->RB_RIGHT;
  366. X    }
  367. X    return 0;
  368. X}
  369. X#endif
  370. X
  371. X#endif /* !RB_MAY_OVERLAP */
  372. X
  373. X#endif /* RB_INTERVALS */
  374. X    
  375. X
  376. X/*
  377. X * Rotating aroud the tree's node adjusting intervals
  378. X */
  379. X#ifndef RB_NOINLINE
  380. Xinline
  381. X#endif
  382. Xstatic void RB_ROTATE_LEFT_(x)
  383. X    register RB_NODE_REF_TYPE x;
  384. X{
  385. X    register RB_NODE_REF_TYPE y;
  386. X
  387. X    y = x->RB_RIGHT;
  388. X    x->RB_RIGHT = y->RB_LEFT;
  389. X    y->RB_LEFT->RB_PARENT = x;    /* can affect the sentinel */
  390. X    y->RB_PARENT = x->RB_PARENT;
  391. X    if( x == x->RB_PARENT->RB_LEFT )
  392. X        x->RB_PARENT->RB_LEFT = y;
  393. X    else
  394. X        x->RB_PARENT->RB_RIGHT = y;
  395. X    y->RB_LEFT = x;
  396. X    x->RB_PARENT = y;
  397. X#ifdef RB_MAY_OVERLAP
  398. X    y->RB_MAX = x->RB_MAX;
  399. X    x->RB_MAX = RB_MAX3_(x);
  400. X#endif
  401. X}
  402. X
  403. X#ifndef RB_NOINLINE
  404. Xinline
  405. X#endif
  406. Xstatic void RB_ROTATE_RIGHT_(x)
  407. X    register RB_NODE_REF_TYPE x;
  408. X{
  409. X    register RB_NODE_REF_TYPE y;
  410. X
  411. X    y = x->RB_LEFT;
  412. X    x->RB_LEFT = y->RB_RIGHT;
  413. X    y->RB_RIGHT->RB_PARENT = x;    /* can affect the sentinel */
  414. X    y->RB_PARENT = x->RB_PARENT;
  415. X    if( x == x->RB_PARENT->RB_RIGHT )
  416. X        x->RB_PARENT->RB_RIGHT = y;
  417. X    else
  418. X        x->RB_PARENT->RB_LEFT = y;
  419. X    y->RB_RIGHT = x;
  420. X    x->RB_PARENT = y;
  421. X#ifdef RB_MAY_OVERLAP
  422. X    y->RB_MAX = x->RB_MAX;
  423. X    x->RB_MAX = RB_MAX3_(x);
  424. X#endif
  425. X}
  426. X        
  427. X
  428. X#ifdef RB_INSERT
  429. X/*
  430. X * Insert into the red-black tree
  431. X */
  432. Xvoid RB_INSERT(t, x)
  433. X    RB_NODE_REF_TYPE          t;
  434. X    register RB_NODE_REF_TYPE x;
  435. X{
  436. X    register RB_NODE_REF_TYPE y, z;
  437. X
  438. X    /*
  439. X     * Standard insertion into binary tree
  440. X     */
  441. X    x->RB_RIGHT = x->RB_LEFT = t;    /* sentinels */
  442. X#ifdef RB_INTERVALS
  443. X    x->RB_MAX = x->RB_END;
  444. X#endif
  445. X    y = t->RB_LEFT;
  446. X    if( y == t ) {
  447. X        t->RB_LEFT = x;
  448. X        x->RB_PARENT = t;
  449. X        RB_SETBLACK(x);
  450. X        return;
  451. X    }
  452. X    z = t;
  453. X    do {
  454. X        z = y;
  455. X        /*
  456. X         * The following three lines are necessary only for
  457. X         * exact-match interval searches
  458. X         */
  459. X#if defined(RB_INTERVALS) && defined(RB_SEARCH)
  460. X        if( RB_EQ(x->RB_BEGIN, y->RB_BEGIN) )
  461. X            y = (RB_LESS(x->RB_END, y->RB_END)) ? y->RB_LEFT : y->RB_RIGHT;
  462. X        else
  463. X#endif
  464. X            y = (RB_LESS(x->RB_BEGIN, y->RB_BEGIN)) ? y->RB_LEFT : y->RB_RIGHT;
  465. X    } while( y != t );
  466. X    x->RB_PARENT = z;
  467. X    if(
  468. X#if defined(RB_INTERVALS) && defined(RB_SEARCH)
  469. X        ((RB_EQ(x->RB_BEGIN, z->RB_BEGIN)) &&
  470. X         (RB_LESS(x->RB_END, z->RB_END))) ||
  471. X#endif
  472. X         (RB_LESS(x->RB_BEGIN, z->RB_BEGIN)) )
  473. X        z->RB_LEFT = x;
  474. X    else
  475. X        z->RB_RIGHT = x;
  476. X
  477. X#ifdef RB_MAY_OVERLAP
  478. X    /*
  479. X     * Adjust maximal values
  480. X     */
  481. X    for( y = z ; y != t ; y = y->RB_PARENT ) {
  482. X        if ( x->RB_END <= y->RB_MAX )
  483. X            break;
  484. X        y->RB_MAX = x->RB_END;
  485. X    } 
  486. X#endif /* RB_MAY_OVERLAP */
  487. X
  488. X    /*
  489. X     * Balancing the tree
  490. X     */
  491. X    RB_SETRED(x);
  492. X    while( RB_ISRED(z) ) {
  493. X        y = z->RB_PARENT->RB_LEFT;
  494. X        if( z == y ) {
  495. X            y = z->RB_PARENT->RB_RIGHT;
  496. X            if( RB_ISRED(y) ) {
  497. X                RB_SETBLACK(z);
  498. X                RB_SETBLACK(y);
  499. X                RB_SETRED(z->RB_PARENT);
  500. X                x = z->RB_PARENT;
  501. X                z = x->RB_PARENT;
  502. X            } else {
  503. X                if( x == z->RB_RIGHT ) {
  504. X                    x = z;
  505. X                    RB_ROTATE_LEFT_(x);
  506. X                    z = x->RB_PARENT;
  507. X                }
  508. X                RB_SETBLACK(z);
  509. X                RB_SETRED(z->RB_PARENT);
  510. X                RB_ROTATE_RIGHT_(z->RB_PARENT);
  511. X            }
  512. X        } else {
  513. X            if( RB_ISRED(y) ) {
  514. X                RB_SETBLACK(z);
  515. X                RB_SETBLACK(y);
  516. X                RB_SETRED(z->RB_PARENT);
  517. X                x = z->RB_PARENT;
  518. X                z = x->RB_PARENT;
  519. X            } else {
  520. X                if( x == z->RB_LEFT ) {
  521. X                    x = z;
  522. X                    RB_ROTATE_RIGHT_(x);
  523. X                    z = x->RB_PARENT;
  524. X                }
  525. X                RB_SETBLACK(z);
  526. X                RB_SETRED(z->RB_PARENT);
  527. X                RB_ROTATE_LEFT_(z->RB_PARENT);
  528. X            }
  529. X        }
  530. X    }
  531. X    RB_SETBLACK(t->RB_LEFT);
  532. X}
  533. X#endif /* RB_INSERT */
  534. X
  535. X#ifdef RB_DELETE
  536. X/*
  537. X * Delete node from red-black tree
  538. X */
  539. Xvoid RB_DELETE(t, w)
  540. X    RB_NODE_REF_TYPE t;
  541. X    register RB_NODE_REF_TYPE w;
  542. X{
  543. X    register RB_NODE_REF_TYPE x;
  544. X    register RB_NODE_REF_TYPE y;
  545. X    register RB_NODE_REF_TYPE z;
  546. X    RB_NODE_REF_TYPE xpar;
  547. X    RB_KEY_TYPE mval;
  548. X    int removed_red;
  549. X
  550. X    xpar = w->RB_PARENT;
  551. X    removed_red = (RB_ISRED(w));
  552. X    if( w->RB_LEFT == t )
  553. X        x = y = w->RB_RIGHT;
  554. X    else if( w->RB_RIGHT == t )
  555. X        x = y = w->RB_LEFT;
  556. X    else {
  557. X        y = w->RB_RIGHT;
  558. X        if( y->RB_LEFT == t ) {
  559. X            x = y->RB_RIGHT;
  560. X            xpar = y;
  561. X        } else {
  562. X            do {
  563. X                y = y->RB_LEFT;
  564. X            } while( y->RB_LEFT != t );
  565. X            x = y->RB_RIGHT;
  566. X            xpar = x->RB_PARENT = y->RB_PARENT;
  567. X            y->RB_PARENT->RB_LEFT = x;
  568. X            y->RB_RIGHT = w->RB_RIGHT;
  569. X            w->RB_RIGHT->RB_PARENT = y;
  570. X        }
  571. X        y->RB_LEFT = w->RB_LEFT;
  572. X        y->RB_LEFT->RB_PARENT = y;
  573. X        removed_red = (RB_ISRED(y));
  574. X        RB_SETBLACK(y);
  575. X        if( RB_ISRED(w) )
  576. X            RB_SETRED(y);
  577. X#ifdef RB_MAY_OVERLAP
  578. X        /* adjust y MAX value */
  579. X        y->RB_MAX = RB_MAX3_(y);
  580. X#endif
  581. X    }
  582. X    z = w->RB_PARENT;
  583. X    y->RB_PARENT = z; 
  584. X    if( z->RB_LEFT == w )
  585. X        z->RB_LEFT = y;
  586. X    else
  587. X        z->RB_RIGHT = y;
  588. X    if( t->RB_LEFT == t )
  589. X        return;
  590. X
  591. X#ifdef RB_MAY_OVERLAP
  592. X    /*
  593. X     * Adjust max values
  594. X     */
  595. X    if( x != y ) {
  596. X        /* this loop cannot reach the root (actually, it cannot reach y) */
  597. X        for( y = xpar ; ; y = y->RB_PARENT ) {
  598. X            mval = RB_MAX3_(y);
  599. X            if( mval == y->RB_MAX )
  600. X                break;
  601. X            y->RB_MAX = mval;
  602. X        }
  603. X    }
  604. X    while( z != t ) {
  605. X        mval = RB_MAX3_(z);
  606. X        if( mval == z->RB_MAX )
  607. X            break;
  608. X        z->RB_MAX = mval;
  609. X        z = z->RB_PARENT;
  610. X    }
  611. X#endif /* RB_MAY_OVERLAP */
  612. X
  613. X    /*
  614. X     * Fix up red-black properties
  615. X     */
  616. X    if( removed_red )
  617. X        return;
  618. X    z = xpar;
  619. X    while( x != t->RB_LEFT && !(RB_ISRED(x)) ) {
  620. X        if( x == z->RB_LEFT ) {
  621. X            y = z->RB_RIGHT;
  622. X            if( RB_ISRED(y) ) {
  623. X                RB_SETBLACK(y);
  624. X                RB_SETRED(z);
  625. X                RB_ROTATE_LEFT_(z);
  626. X                y = z->RB_RIGHT;
  627. X            }
  628. X            if( !(RB_ISRED(y->RB_LEFT)) && !(RB_ISRED(y->RB_RIGHT)) ) {
  629. X                RB_SETRED(y);
  630. X                x = z;
  631. X                z = x->RB_PARENT;
  632. X            } else {
  633. X                if( !(RB_ISRED(y->RB_RIGHT)) ) {
  634. X                    /* y->RB_LEFT cannot be nil */
  635. X                    RB_SETBLACK(y->RB_LEFT);
  636. X                    RB_SETRED(y);
  637. X                    RB_ROTATE_RIGHT_(y);
  638. X                    y = z->RB_RIGHT;
  639. X                }
  640. X                RB_SETBLACK(y);
  641. X                if( RB_ISRED(z) )
  642. X                    RB_SETRED(y);
  643. X                RB_SETBLACK(z);
  644. X                RB_SETBLACK(y->RB_RIGHT);
  645. X                RB_ROTATE_LEFT_(z);
  646. X                break;
  647. X            }
  648. X        } else {
  649. X            y = z->RB_LEFT;
  650. X            if( RB_ISRED(y) ) {
  651. X                RB_SETBLACK(y);
  652. X                RB_SETRED(z);
  653. X                RB_ROTATE_RIGHT_(z);
  654. X                y = z->RB_LEFT;
  655. X            }
  656. X            if( !(RB_ISRED(y->RB_LEFT)) && !(RB_ISRED(y->RB_RIGHT)) ) {
  657. X                RB_SETRED(y);
  658. X                x = z;
  659. X                z = x->RB_PARENT;
  660. X            } else {
  661. X                if( !(RB_ISRED(y->RB_LEFT)) ) {
  662. X                    /* y->RB_RIGHT cannot be nil */
  663. X                    RB_SETBLACK(y->RB_RIGHT);
  664. X                    RB_SETRED(y);
  665. X                    RB_ROTATE_LEFT_(y);
  666. X                    y = z->RB_LEFT;
  667. X                }
  668. X                RB_SETBLACK(y);
  669. X                if( RB_ISRED(z) )
  670. X                    RB_SETRED(y);
  671. X                RB_SETBLACK(z);
  672. X                RB_SETBLACK(y->RB_LEFT);
  673. X                RB_ROTATE_RIGHT_(z);
  674. X                break;
  675. X            }
  676. X        }
  677. X    }
  678. X    RB_SETBLACK(x);
  679. X}
  680. X#endif /* RB_DELETE */
  681. X
  682. X#ifdef RB_INITIALIZE
  683. X/*
  684. X * Initialize the tree header/nil sentinel
  685. X */
  686. Xvoid RB_INITIALIZE(t)
  687. X    register RB_NODE_REF_TYPE t;
  688. X{
  689. X    t->RB_LEFT = t->RB_RIGHT = t->RB_PARENT = t;
  690. X    t->RB_BEGIN = RB_MINIMAL_KEY;
  691. X#ifdef RB_INTERVALS
  692. X    t->RB_END = RB_MINIMAL_KEY;
  693. X#ifdef RB_MAY_OVERLAP
  694. X    t->RB_MAX = RB_MINIMAL_KEY;
  695. X#endif
  696. X#endif /* RB_INTERVALS */
  697. X    RB_SETBLACK(t);
  698. X}
  699. X#endif /* RB_INITIALIZE */
  700. X
  701. X
  702. X#if defined(RB_PRINT) && defined(RB_PRINT_)
  703. X
  704. X#ifndef RB_KEY_FMT
  705. X#define RB_KEY_FMT "%x"
  706. X#endif
  707. X
  708. X/*
  709. X * Printing the tree nodes in increasing order
  710. X */
  711. Xstatic void RB_PRINT_(t, tt, l)
  712. X    register RB_NODE_REF_TYPE t;
  713. X    register RB_NODE_REF_TYPE tt;
  714. X    int l;
  715. X{
  716. X    if( t->RB_LEFT != tt )
  717. X        RB_PRINT_(t->RB_LEFT, tt, l+1);
  718. X    printf("%*s%x [%c] ", l*4, "", t, (RB_ISRED(t))? 'R' : 'B');
  719. X    printf(RB_KEY_FMT, t->RB_BEGIN);
  720. X#ifdef RB_INTERVALS
  721. X    printf("-");
  722. X    printf(RB_KEY_FMT, t->RB_END);
  723. X#ifdef RB_MAY_OVERLAP
  724. X    printf(" max=");
  725. X    printf(RB_KEY_FMT, t->RB_MAX);
  726. X#endif
  727. X#endif /* RB_INTERVALS */
  728. X    printf(t->RB_LEFT   == tt? " l=NIL": " l=%x", t->RB_LEFT);
  729. X    printf(t->RB_RIGHT  == tt? " r=NIL": " r=%x", t->RB_RIGHT);
  730. X    printf(t->RB_PARENT == tt? " p=NIL": " p=%x", t->RB_PARENT);
  731. X#ifdef RB_XPRINTF
  732. X    RB_XPRINTF(t);
  733. X#endif
  734. X    printf("\n");
  735. X    if( t->RB_RIGHT != tt )
  736. X        RB_PRINT_(t->RB_RIGHT, tt, l+1);
  737. X}
  738. X
  739. X/*
  740. X * Print out the tree
  741. X */
  742. Xvoid RB_PRINT(t)
  743. X    register RB_NODE_REF_TYPE t;
  744. X{
  745. X    if( t->RB_LEFT == t )
  746. X        printf("EMPTY\n");
  747. X    else
  748. X        RB_PRINT_(t->RB_LEFT, t, 0);
  749. X}
  750. X#endif /* RB_PRINT */
  751. X
  752. X/*
  753. X * Recursive verification step
  754. X */
  755. X
  756. X    
  757. X/*
  758. X * Un-define the module parameters
  759. X */
  760. X#undef    RB_INTERVALS
  761. X#undef    RB_MAY_OVERLAP
  762. X#undef    RB_MINIMAL_KEY
  763. X#undef    RB_NODE_REF_TYPE
  764. X#undef    RB_KEY_TYPE
  765. X#undef    RB_LESS(a, b) 
  766. X#undef    RB_EQ(a, b)
  767. X#undef    RB_ISRED(node)
  768. X#undef    RB_SETRED(node)    
  769. X#undef    RB_SETBLACK(node)
  770. X#undef    RB_NO_INLINES
  771. X#undef    RB_KEY_FMT
  772. X#undef    RB_XPRINTF
  773. X
  774. X#undef    RB_SCAN1
  775. X#undef    RB_SCAN2
  776. X#undef    RB_SCAN3
  777. X#undef    RB_SCAN_PROC1
  778. X#undef    RB_SCAN_PROC2
  779. X#undef    RB_SCAN_PROC3
  780. X#undef    RB_SCAN1_ORDERED
  781. X#undef    RB_SCAN2_ORDERED
  782. X#undef    RB_SCAN3_ORDERED
  783. X#undef    RB_SEARCH
  784. X#undef    RB_OVERLAP
  785. X#undef    RB_INSERT
  786. X#undef    RB_DELETE
  787. X#undef    RB_INITIALIZE
  788. X#undef    RB_PRINT
  789. X
  790. X#undef    RB_MAX3_
  791. X#undef    RB_ROTATE_RIGHT_
  792. X#undef    RB_ROTATE_LEFT_
  793. X#undef    RB_PRINT_
  794. X
  795. X#undef    RB_BEGIN
  796. X#undef    RB_END
  797. X#undef    RB_MAX
  798. X#undef    RB_LEFT
  799. X#undef    RB_RIGHT
  800. X#undef    RB_PARENT
  801. END-of-rb-generic.c
  802. echo x - rb-test.c
  803. sed 's/^X//' >rb-test.c << 'END-of-rb-test.c'
  804. X
  805. X/*
  806. X * Copyright 1991, Vadim Antonov
  807. X * All rights reserved.
  808. X *
  809. X * This code is developed as a part of Grail project and can
  810. X * be used and redistributed freely as long as this copyright
  811. X * notice is retained.
  812. X *
  813. X * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES.
  814. X */
  815. X
  816. X/* Revision 1.0, 7-12-1991 */
  817. X
  818. X#include <stdio.h>
  819. X#include <assert.h>
  820. X
  821. X/*
  822. X * Red-Black tree node
  823. X */
  824. X
  825. Xtypedef struct RBNODE *rbnode;
  826. X
  827. Xstruct RBNODE {
  828. X    int    rb_red;        /* node is red */
  829. X    int    rb_begin;    /* beginning of the interval */
  830. X    int    rb_end;        /* end of the interval */
  831. X    int    rb_max;        /* highest value in the subtree */
  832. X    rbnode    rb_left;    /* left link */
  833. X    rbnode    rb_right;    /* right link */
  834. X    rbnode    rb_parent;    /* parent link */
  835. X};
  836. X
  837. X
  838. X/*
  839. X * Include generic routines
  840. X */
  841. X#define RB_INTERVALS
  842. X#undef RB_MAY_OVERLAP
  843. X#define RB_MINIMAL_KEY        (~0)
  844. X#define RB_NODE_REF_TYPE    rbnode
  845. X#define RB_KEY_TYPE        int
  846. X#define RB_LESS(a,b)        a < b
  847. X#define RB_EQ(a,b)        a == b
  848. X#define RB_ISRED(x)        x->rb_red
  849. X#define RB_SETRED(x)        x->rb_red = 1
  850. X#define RB_SETBLACK(x)        x->rb_red = 0
  851. X#define RB_DEBUG
  852. X#define RB_KEY_FMT        "%d"
  853. X#define RB_SCAN1        rbi_scan1
  854. X#define RB_SCAN_PROC1(x)    printf("(%d-%d) ", x->rb_begin, x->rb_end)
  855. X#define RB_SCAN2        rbi_scan2
  856. X#define RB_SCAN_PROC2(x)    printf("(%d-%d) ", x->rb_begin, x->rb_end)
  857. X#define RB_SCAN2_ORDERED
  858. X#define RB_SEARCH        rbi_search
  859. X#define RB_OVERLAP        rbi_overlap
  860. X#define RB_INSERT        rbi_insert
  861. X#define RB_DELETE        rbi_delete
  862. X#define RB_INITIALIZE        rbi_initialize
  863. X#define RB_PRINT        rbi_print
  864. X
  865. X#define RB_MAX3_        _rbi_max3
  866. X#define RB_ROTATE_LEFT_        _rbi_rleft
  867. X#define RB_ROTATE_RIGHT_    _rbi_rright
  868. X#define RB_PRINT_        _rbi_print
  869. X
  870. X#define RB_BEGIN        rb_begin
  871. X#define RB_END            rb_end
  872. X#define RB_MAX            rb_max
  873. X#define RB_LEFT            rb_left
  874. X#define RB_RIGHT        rb_right
  875. X#define RB_PARENT        rb_parent
  876. X
  877. X#include "rb-generic.c"
  878. X
  879. X#ifdef NOTYET
  880. X#define MAXNODES 20000
  881. Xint nnodes;
  882. Xrbnode nodes[MAXNODES];
  883. X#endif /*NOTYET*/
  884. X
  885. X/*
  886. X * Debugging routines
  887. X */
  888. Xmain()
  889. X{
  890. X    char line[100];
  891. X    char *p;
  892. X    struct RBNODE tree;
  893. X    rbnode x;
  894. X    int i, j;
  895. X    char *index();
  896. X
  897. X    rbi_initialize(&tree);
  898. X    for(;;) {
  899. X        printf("> ");
  900. X        fflush(stdout);
  901. X        fgets(line, 100, stdin);
  902. X        if( (p = index(line, '\n')) != NULL )
  903. X            *p = 0;
  904. X        p = line;
  905. X        while( *p && *p != ' ' ) p++;
  906. X        while( *p == ' ' ) p++;
  907. X        switch( line[0] ) {
  908. X        default:
  909. X            printf("valid commands: q, p, s key, a key, d key\n");
  910. X            break;
  911. X        case 0:
  912. X            break;
  913. X        case 'q':
  914. X            exit(0);
  915. X        case 'p':
  916. X            rbi_print(&tree);
  917. X            break;
  918. X        case 'S':
  919. X            i = atoi(p);
  920. X            if( i == 1 )
  921. X                rbi_scan1(&tree);
  922. X            else if( i == 2 )
  923. X                rbi_scan2(&tree);    
  924. X            else
  925. X                printf("Scan 1,2 only");
  926. X            printf("\n");
  927. X            break;
  928. X        case 's':
  929. X            i = atoi(p);
  930. X            while( *p && *p != ' ' ) p++;
  931. X            while( *p == ' ' ) p++;
  932. X            j = atoi(p);
  933. X            x = rbi_search(&tree, i, j);
  934. X            if( x == 0 ) 
  935. X                printf("%d-%d not found\n", i, j);
  936. X            else
  937. X                printf("%d-%d ==> %x\n", i,j, x);
  938. X            break;
  939. X        case 'o':
  940. X            i = atoi(p);
  941. X            while( *p && *p != ' ' ) p++;
  942. X            while( *p == ' ' ) p++;
  943. X            j = atoi(p);
  944. X            x = rbi_overlap(&tree, i, j);
  945. X            if( x == 0 ) 
  946. X                printf("%d-%d not found\n", i, j);
  947. X            else
  948. X                printf("%d-%d overlaps with %d-%d (%x)\n", i,j, x->rb_begin, x->rb_end, x);
  949. X            break;
  950. X        case 'a':
  951. X            i = atoi(p);
  952. X            while( *p && *p != ' ' ) p++;
  953. X            while( *p == ' ' ) p++;
  954. X            j = atoi(p);
  955. X            if( i > j ) {
  956. X                printf("Inverted interval");
  957. X                break;
  958. X            }
  959. X            x = (rbnode)malloc(sizeof(struct RBNODE));
  960. X            x->rb_begin = i;
  961. X            x->rb_end = j;
  962. X            rbi_insert(&tree, x);
  963. X            break;
  964. X        case 'd':
  965. X            i = atoi(p);
  966. X            while( *p && *p != ' ' ) p++;
  967. X            while( *p == ' ' ) p++;
  968. X            j = atoi(p);
  969. X            x = rbi_search(&tree, i, j);
  970. X            if (x == 0)
  971. X                printf("No such node\n");
  972. X            else {
  973. X                rbi_delete(&tree, x);
  974. X                free(x);
  975. X            }
  976. X            break;
  977. X/*
  978. X        case 'v':
  979. X            rbvrfy(&tree);
  980. X            break;
  981. X*/
  982. X#ifdef NOTYET
  983. X        case 'S':
  984. X            i = atoi(p);
  985. X            srand(i);
  986. X            printf("SEED %d\n", i);
  987. X            break;
  988. X        case 'A':
  989. X            i = atoi(p);
  990. X            while( i-- > 0 ) {
  991. X                if (nnodes >= MAXNODES)
  992. X                    break;
  993. X                x = (rbnode)malloc(sizeof(struct RBNODE));
  994. X                x->key = rand();
  995. X                nodes[nnodes++] = x;
  996. X                rbinsert(&tree, x);
  997. X            }
  998. X            printf("%d NODES\n", nnodes);
  999. X            break;
  1000. X
  1001. X        case 'D':
  1002. X            i = atoi(p);
  1003. X            while( i-- > 0 ) {
  1004. X                if (nnodes <= 0)
  1005. X                    break;
  1006. X                j = rand();
  1007. X                if( j < 0 )
  1008. X                    j = -j;
  1009. X                j %= nnodes;
  1010. X                x = nodes[j];
  1011. X                nodes[j] = nodes[--nnodes];
  1012. X                rbdelete(&tree, x);
  1013. X                free(x);
  1014. X            }
  1015. X            printf("%d NODES\n", nnodes);
  1016. X            break;
  1017. X#endif /*NOTYET*/
  1018. X        }
  1019. X    }
  1020. X}
  1021. END-of-rb-test.c
  1022. exit
  1023.  
  1024.