home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / m2sply22 / part01 < prev    next >
Encoding:
Text File  |  1993-01-19  |  34.2 KB  |  1,234 lines

  1. Newsgroups: comp.sources.misc
  2. From: ljp@sm.luth.se (Johan Persson)
  3. Subject: v35i002:  m2-splay22 - Modula-2 splay tree library, Part01/01
  4. Message-ID: <1993Jan21.001939.29846@sparky.imd.sterling.com>
  5. X-Md4-Signature: 06df3818963bd2e1b051f632be107c60
  6. Date: Thu, 21 Jan 1993 00:19:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ljp@sm.luth.se (Johan Persson)
  10. Posting-number: Volume 35, Issue 2
  11. Archive-name: m2-splay22/part01
  12. Environment: Modula-2
  13.  
  14. This is a Modula-2 library to implement splay trees.
  15.  
  16. Splay trees are a form of balanced binary trees which moves every 
  17. accessed node to the root.  This means that the tree will behave 
  18. very well when there is some form of locality in the data processed. 
  19. Furthermore it can be shown that the amortized access cost is O(lgn) 
  20. for the basic operations (insert, delete and find).
  21.  
  22. The splay tree also has the nice property that an item accessed
  23. t operations ago can be located in O(lgt) time.
  24.  
  25. All in all practical tests have shown splay trees to be an excellent
  26. substitution for the more well known r-b-trees or some other variations
  27. on balanced trees.
  28.  
  29. For a full introduction to splay trees see 
  30.  
  31.         Sleator D. and Tarjan R. "Self adjusting
  32.     binary trees", JACM Vol 32. No 3, 1985, pp 652-686.
  33.  
  34. -------------------------------8<----------------------------------------
  35. #! /bin/sh
  36. # This is a shell archive.  Remove anything before this line, then feed it
  37. # into a shell via "sh file" or similar.  To overwrite existing files,
  38. # type "sh file -c".
  39. # Contents:  README splay.def splay.mod splayItem.def splayItem.mod
  40. #   splayTest.mod
  41. # Wrapped by kent@sparky on Wed Jan 20 17:56:09 1993
  42. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  43. echo If this archive is complete, you will see the following message:
  44. echo '          "shar: End of archive 1 (of 1)."'
  45. if test -f 'README' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'README'\"
  47. else
  48.   echo shar: Extracting \"'README'\" \(4498 characters\)
  49.   sed "s/^X//" >'README' <<'END_OF_FILE'
  50. XSPLAY TREE LIBRARY Version 2.2 930119
  51. X=====================================
  52. X
  53. XThis library contains the following files:
  54. X
  55. X    splay.def    Definition module for the splay tree library
  56. X    splay.mod     Implementation of splay tree
  57. X    splayItem.def     Definition module for data stored in the tree
  58. X    splayItem.mod    Implementation module for data stored in
  59. X            the tree
  60. X    splayTest.mod    A short test program
  61. X
  62. X
  63. X
  64. XFor a full introduction to splay trees see 
  65. X
  66. X                    Sleator D. and Tarjan R. "Self adjusting
  67. X            binary trees", JACM Vol 32. No 3, 1985, pp 652-
  68. X            686.
  69. X
  70. X
  71. X
  72. XChanges since version 2.1
  73. X=========================
  74. X
  75. XChanged updating of weight information so the basic operations
  76. Xnow remain in O(lgn) instead of O(n).
  77. X
  78. X
  79. XIntroduction
  80. X============
  81. X
  82. XIn short, splay trees are a form of balanced binary trees which
  83. Xmoves every accessed node to the root. This means that the tree
  84. Xwill behave very well when there is some form of locality in the
  85. Xdata processed. Furthermore it can be shown that the amortized
  86. Xaccess cost is O(lgn) for the basic operations (insert, delete and
  87. Xfind).
  88. X
  89. XThe splay tree also has the nice property that an item accessed
  90. Xt operations ago can be located in O(lgt) time.
  91. X
  92. XAll in all practical tests have shown splay trees to be an excellent
  93. Xsubstitution for the more well known r-b-trees or some other variations
  94. Xon balanced trees.
  95. X
  96. XSince modula2 lacks possibilities to create generic modules my
  97. Xapproach is to provide a separate module which gives the operations
  98. Xand type of the element stored in the tree. This module
  99. X(here called splayItem) must support operations to create, destroy
  100. Xand compare elements. This scheme provides for a fairly generic
  101. Ximplementation, (see the test program and splayItem.[mod,def])
  102. XIn the test program supplied the create and destroy routines
  103. Xare empty since the objects doesn't use any dynamic memory. The
  104. Xprize to pay for the generic structure is a little overhead for
  105. Xeach comparison.
  106. X
  107. XIf speed is essential (as always) you may hard code the comparison
  108. Xbetween elements in the implementation if you are only working
  109. Xwith simple types like integers or something like that. Or you
  110. Xmight want to rewrite the code to handle the more classic
  111. Xvariation with a key and a generic pointer stored in each
  112. Xnode. These changes are trivial and shouldn't take long
  113. Xtime to do.
  114. X
  115. X
  116. XRank
  117. X====
  118. X
  119. XThis implementation includes management of the rank of elements, i.e
  120. Xtheir ordering in an in-order tree traversal. To maintain the rank operation
  121. Xin O(lgn) time for an element it's necessary to do some extra work
  122. Xafter each basic operation. If you are not interested in maintaining
  123. Xrank of the elements you may delete the code for maintaining the weight
  124. X(number of nodes in subtrees for each node) of each node. 
  125. X
  126. XThis is basically a matter of deleting most of the code at the end of
  127. Xeach basic operation.
  128. X
  129. XSince maintaining the rank requires an explicit stack whos size
  130. Xmust be decided at run time it's possible to get a checked run time
  131. Xerror if the tree grows to large for the stack. This shouldn't pose
  132. Xa problem since the required stack size is in order O(lgn) where
  133. Xn is the number of elements in the tree, and the default stack quite
  134. Xbig.
  135. X
  136. XPortability
  137. X===========
  138. X
  139. XThere are basically two things you may want to change.
  140. X
  141. X1. The first are the routines used for I/O to
  142. Xprint a string, cardinal, int and so on. I have used
  143. Xour local library routines. Change these to your own
  144. Xfavorites.
  145. X
  146. X2. Error handling are done by a call to error.raise() which
  147. Xagain is a local library function. It calls the topmost
  148. Xfunction in an error stack with the string supplied as 
  149. Xargument. You probably want to change this to your own
  150. Xfavorite way of handling errors.
  151. X
  152. XTodo
  153. X====
  154. X
  155. X* Make two versions one with and one without rank operations.
  156. X* Dynamic stack to avoid any run time errors
  157. X
  158. X
  159. XTest program
  160. X============
  161. X
  162. XSupplied with this distribution is a test program called
  163. XsplayTest (what else?) it performs some basic tests at first
  164. Xand then starts an exhaustive test until any errors have been
  165. Xencountered or stopped by a CTRL-C. 
  166. X
  167. XBugs
  168. X====
  169. XTo the best of my knowledge this code is bug free. But if you
  170. Xdo discover some irregularities please drop me a note. 
  171. X
  172. XStandard disclaimer: This code is put in public domain and 
  173. Xdistributed as is. You may use this code commercially or 
  174. Xotherwise but I won't take any responsibility whatsoever.
  175. X
  176. X
  177. X    Johan Persson (ljp@sm.luth.se)
  178. X
  179. X
  180. X----
  181. X
  182. XJohan Persson                E-mail: ljp@sm.luth.se
  183. XDept. of Computer Science
  184. XTechnical University of Lulea
  185. XS-951 87 Lulea
  186. X            
  187. END_OF_FILE
  188.   if test 4498 -ne `wc -c <'README'`; then
  189.     echo shar: \"'README'\" unpacked with wrong size!
  190.   fi
  191.   # end of 'README'
  192. fi
  193. if test -f 'splay.def' -a "${1}" != "-c" ; then 
  194.   echo shar: Will not clobber existing file \"'splay.def'\"
  195. else
  196.   echo shar: Extracting \"'splay.def'\" \(3840 characters\)
  197.   sed "s/^X//" >'splay.def' <<'END_OF_FILE'
  198. XDEFINITION MODULE splay;
  199. X(*
  200. X    Title:        Implementation of splay trees
  201. X    Last Edit:    Mon Dec 21 13:20:31 1992
  202. X    Author:        Johan Persson at my16
  203. X
  204. X    SCCS:        @(#)splay.def       2.2     92/12/21
  205. X
  206. X    Description:    This code implements splay tree as described in 
  207. X                    Sleator D. and Tarjan R. "Self adjusting
  208. X            binary trees", JACM Vol 32. No 3, 1985, pp 652-
  209. X            686.
  210. X            
  211. X            The implemenation is based on a top down
  212. X                        splaying heuristics as described in section 4 of 
  213. X            the article.
  214. X
  215. X    Note:        This implementation also supports the operations
  216. X            'getRankElement' which finds the element in the tree
  217. X            with a given rank in O(lgn) time) and 'getRank', 
  218. X            (which returns the rank of a given element)
  219. X            To achive this one must store the weight of a node in
  220. X            each node (i.e the number of descadents). The
  221. X            update of this information after each basic 
  222. X            operation takes O(lgn) time.
  223. X            
  224. X            To maintain this weight it's necessary to use a
  225. X            stack, since the size of the stack is 
  226. X            specified at compile time this may cause a checked 
  227. X            run time error if the bounds of this stack is 
  228. X                violated. 
  229. X*)
  230. X
  231. X  IMPORT splayItem;
  232. X
  233. X  TYPE
  234. X     auxFunc = PROCEDURE (splayItem.T);
  235. X     T;
  236. X
  237. X  PROCEDURE create(VAR tree:T);
  238. X  (* Post: The splay tree tree 'tree' has been created.
  239. X  *)
  240. X           
  241. X  PROCEDURE destroy(VAR tree:T);
  242. X  (* Pre: 'tree' has been created with 'create'
  243. X     Post: All dynamic memory previously associated with 'tree'
  244. X           have been returned. The 'del' function specified in
  245. X       'create' has been called one time for each datum in the
  246. X       tree. Upon completion 'tree' is no longer a valid tree.
  247. X  *) 
  248. X  
  249. X  PROCEDURE insert(tree:T; item:splayItem.T);
  250. X  (* Pre: 'tree' has been created with 'create'
  251. X     Post: 'item' has been inserted in 'tree'. If the 'item' already
  252. X           exists this operation equals 
  253. X          delete(tree,item);insert(tree,item)
  254. X  *)
  255. X  
  256. X  PROCEDURE delete(tree:T; item:splayItem.T);
  257. X  (* Pre: 'tree' has been created with 'create'
  258. X     Post: If 'item' exists it has been removed from 'tree'
  259. X           otherwise the tree is left untouched
  260. X  *)
  261. X  
  262. X  PROCEDURE find(tree:T; item:splayItem.T; VAR found:splayItem.T):BOOLEAN;
  263. X  (* Pre: 'tree' has been created with 'create'
  264. X     Post: If 'item' exists in 'tree' 'found' has been assigned
  265. X           to the corresponding data in 'tree'.
  266. X       Note: The reason for returning the same item searched
  267. X             for is to make it possible to specify an incomplete
  268. X         search structure and then get the full structure
  269. X         returned.
  270. X     Returns: TRUE if 'item' exist, FALSE otherwise
  271. X  *)
  272. X  
  273. X  PROCEDURE nbrElem(tree:T): CARDINAL;
  274. X  (* Pre: 'tree' has been created with 'create'
  275. X     Returns: The number of elements in 'tree'
  276. X  *)
  277. X  
  278. X  PROCEDURE getRankElement(tree:T; r:CARDINAL; VAR found:splayItem.T): BOOLEAN;
  279. X  (* Pre: 'tree' has been created with 'create'
  280. X     Post: The 'item' with rank 'r' has been assigned to 'found'
  281. X     Returns: TRUE if 'item' exist, FALSE otherwise
  282. X  *)
  283. X  
  284. X  PROCEDURE getRank(tree:T; item:splayItem.T):CARDINAL;
  285. X  (* Pre: 'tree' has been created with 'create'
  286. X     Returns: The rank of element 'item'. If 'item' wasn't 
  287. X              found the routine returns 0 
  288. X  *)
  289. X  
  290. X  PROCEDURE mapIn(tree:T; f:auxFunc);
  291. X  (* Pre: 'tree' has been created with 'create'
  292. X     Post: The 'f' procedure has been applied to all elements in
  293. X           'tree' according to a tree-inorder walk
  294. X  *)
  295. X  
  296. X  PROCEDURE mapPre(tree:T; f:auxFunc);
  297. X  (* Pre: 'tree' has been created with 'create'
  298. X     Post: The 'f' procedure has been applied to all elements in
  299. X           'tree' according to a tree-preorder walk
  300. X  *)
  301. X  
  302. X  PROCEDURE mapPos(tree:T; f:auxFunc); 
  303. X  (* Pre: 'tree' has been created with 'create'
  304. X     Post: The 'f' procedure has been applied to all elements in
  305. X           'tree' according to a tree-preorder walk
  306. X  *)
  307. X
  308. XEND splay.
  309. END_OF_FILE
  310.   if test 3840 -ne `wc -c <'splay.def'`; then
  311.     echo shar: \"'splay.def'\" unpacked with wrong size!
  312.   fi
  313.   # end of 'splay.def'
  314. fi
  315. if test -f 'splay.mod' -a "${1}" != "-c" ; then 
  316.   echo shar: Will not clobber existing file \"'splay.mod'\"
  317. else
  318.   echo shar: Extracting \"'splay.mod'\" \(15974 characters\)
  319.   sed "s/^X//" >'splay.mod' <<'END_OF_FILE'
  320. XIMPLEMENTATION MODULE splay;
  321. X(*
  322. X    Title:        Implementation of splay trees
  323. X    Last Edit:    Mon Dec 21 13:20:38 1992
  324. X    Author:        Johan Persson at my16
  325. X    SCCS:        @(#)splay.mod       2.2     92/12/21    
  326. X    
  327. X        
  328. X    Description:    This code implements splay tree as described in 
  329. X                    Sleator D. and Tarjan R. "Self adjusting
  330. X            binary trees", JACM Vol 32. No 3, 1985, pp 652-
  331. X            686.
  332. X            
  333. X            The implemenation is based on a top down
  334. X                        splaying heuristics as described in section 4 of 
  335. X            the article.
  336. X
  337. X    Note:        This implementation also supports the operations
  338. X            'getRankElement' which finds the element in the tree
  339. X            with a given rank in O(lgn) time) and 'getRank', 
  340. X            (which returns the rank of a given element)
  341. X            To achive this one must store the weight of a node in
  342. X            each node (i.e the number of descadents). The
  343. X            update of this information after each basic 
  344. X            operation takes O(lgn) time.
  345. X
  346. X            To maintain this weight it's necessary to use a
  347. X            stack, since the size of the stack is 
  348. X            specified at compile time this may cause a checked 
  349. X            run time error if the bounds of this stack is 
  350. X                violated. 
  351. X
  352. X            See 'splay.def' for a complete description
  353. X            of all procedures.
  354. X*)
  355. X
  356. X  IMPORT SYSTEM,Storage,splayItem,error; 
  357. X   
  358. X  TYPE
  359. X     T = POINTER TO head;
  360. X     Tree = POINTER TO treeNode;
  361. X     treeNode = RECORD
  362. X           l,r:Tree;          (* left and right links   *)
  363. X           data:splayItem.T;      (* stored item            *)
  364. X           weight:CARDINAL;      (* number of nodes in subtrees *)
  365. X        END (* record *);         
  366. X        
  367. X     cmpFunc = PROCEDURE (splayItem.T, splayItem.T) : CARDINAL;
  368. X    
  369. X     head = RECORD
  370. X            t : Tree;
  371. X          nbr : CARDINAL;   
  372. X        END (* record *);
  373. X        
  374. X    CONST 
  375. X      stackSize =  10000;
  376. X              
  377. X    VAR 
  378. X         ls : ARRAY [0..stackSize] OF Tree;
  379. X         rs : ARRAY [0..stackSize] OF Tree;
  380. X     lp,rp : CARDINAL;
  381. X
  382. X
  383. X    PROCEDURE create(VAR tree:T);
  384. X       BEGIN (* create *)
  385. X         Storage.ALLOCATE(tree,SIZE(head));
  386. X     tree^.t := NIL;
  387. X     tree^.nbr := 0;
  388. X       END create;
  389. X
  390. X
  391. X  PROCEDURE destroy(VAR tree:T);
  392. X     PROCEDURE des(t:Tree);
  393. X       BEGIN (* des *)
  394. X     IF t # NIL THEN 
  395. X        des(t^.l);
  396. X        des(t^.r);
  397. X        splayItem.destroy(t^.data);
  398. X        Storage.DEALLOCATE(t,SIZE(treeNode));
  399. X     END (* if *);
  400. X       END des;
  401. X     BEGIN (* destroy *)
  402. X       des(tree^.t); 
  403. X       Storage.DEALLOCATE(tree,SIZE(head));
  404. X       tree := NIL;
  405. X     END destroy;
  406. X  
  407. X   PROCEDURE nbrElem(tree:T): CARDINAL; 
  408. X      BEGIN
  409. X         RETURN tree^.nbr;
  410. X      END nbrElem;
  411. X     
  412. X(* *)
  413. X  PROCEDURE insert(tree:T; item:splayItem.T);
  414. X     VAR n,nn,l,r,node:Tree;
  415. X         i:CARDINAL;
  416. X     BEGIN (* insert *)
  417. X       Storage.ALLOCATE(node,SIZE(treeNode));
  418. X       node^.data := item; 
  419. X       n := tree^.t;
  420. X       lp:=0;rp:=0;ls[0]:=NIL;rs[0]:=NIL;
  421. X       tree^.t := node;
  422. X       IF n = NIL THEN
  423. X            node^.l:=NIL; node^.r:=NIL;
  424. X       ELSE 
  425. X            l:=node; r:=node;
  426. X     ls[0]:=l; rs[0]:=r;
  427. X     LOOP 
  428. X       IF l#ls[lp] THEN INC(lp);
  429. X         IF lp>stackSize THEN error.raise("Internal error splay(insert):\n");HALT;
  430. X         ELSE ls[lp]:=l; END;
  431. X       END;
  432. X       IF r#rs[rp] THEN INC(rp); 
  433. X         IF rp>stackSize THEN error.raise("Internal error splay(insert):\n");HALT;
  434. X         ELSE rs[rp]:=r; END;
  435. X       END;
  436. X     
  437. X       IF splayItem.cmp(item,n^.data) < 0 THEN 
  438. X         nn := n^.l;
  439. X         IF nn=NIL THEN r^.l := n; l^.r := NIL; EXIT;
  440. X         ELSIF splayItem.cmp(item,nn^.data) >= 0 THEN 
  441. X           r^.l := n; r := n; 
  442. X           l^.r := nn; l := nn;
  443. X           n := nn^.r;
  444. X           IF n=NIL THEN r^.l:=NIL; EXIT; END;
  445. X         ELSE (* item < data *)
  446. X           n^.l := nn^.r;
  447. X           r^.l := nn;
  448. X           nn^.r := n;
  449. X           r := nn;
  450. X           n := nn^.l;
  451. X           IF n = NIL THEN l^.r := NIL; EXIT; END;
  452. X         END (* if *);
  453. X       ELSE (* item >= data *)   
  454. X         nn := n^.r;
  455. X         IF nn=NIL THEN l^.r := n; r^.l := NIL; EXIT;
  456. X         ELSIF splayItem.cmp(item,nn^.data) < 0 THEN 
  457. X           l^.r := n; l := n; 
  458. X           r^.l := nn; r:=nn;
  459. X           n := nn^.l;
  460. X           IF n=NIL THEN l^.r:=NIL; EXIT; END;
  461. X         ELSE (* item >= data *)
  462. X           n^.r := nn^.l;
  463. X           l^.r := nn;
  464. X           nn^.l := n;
  465. X           l := nn;
  466. X           n := nn^.r;
  467. X           IF n=NIL THEN r^.l := NIL; EXIT; END;
  468. X         END (* if *)
  469. X       END (* if *);
  470. X     END (* loop *);
  471. X     IF l#ls[lp] THEN INC(lp); ls[lp]:=l; END;
  472. X     IF r#rs[rp] THEN INC(rp); rs[rp]:=r; END; 
  473. X     (*
  474. X     ** Now, walk back up the left AND right built tree, i.e all nodes
  475. X     ** that are smaller (and bigger) than the node searched for, 
  476. X     ** and update all weights. This is done using an explicit stack ls
  477. X     ** and lr.
  478. X     *) 
  479. X     FOR i := lp TO 0 BY -1 DO
  480. X        n:=ls[i]; n^.weight:=1;
  481. X        nn:=n^.l;
  482. X        IF nn#NIL THEN 
  483. X           nn^.weight:=1;           
  484. X           IF nn^.l#NIL THEN nn^.weight:=nn^.weight+nn^.l^.weight; END;
  485. X           IF nn^.r#NIL THEN nn^.weight:=nn^.weight+nn^.r^.weight; END;
  486. X           n^.weight:=n^.weight+nn^.weight; 
  487. X        END;
  488. X        nn:=n^.r;
  489. X        IF nn#NIL THEN n^.weight:=n^.weight+nn^.weight; END;
  490. X     END (* for *);
  491. X     
  492. X     FOR i := rp TO 0 BY -1 DO
  493. X        n:=rs[i]; n^.weight:=1;
  494. X        nn:=n^.r;
  495. X        IF nn#NIL THEN 
  496. X           nn^.weight:=1;
  497. X           IF nn^.l#NIL THEN nn^.weight:=nn^.weight+nn^.l^.weight; END;
  498. X           IF nn^.r#NIL THEN nn^.weight:=nn^.weight+nn^.r^.weight; END;
  499. X           n^.weight:=n^.weight+nn^.weight; 
  500. X        END;
  501. X        nn:=n^.l;
  502. X        IF nn#NIL THEN n^.weight:=n^.weight+nn^.weight; END;
  503. X     END (* for *); 
  504. X     
  505. X     nn := node^.r;
  506. X     node^.r := node^.l;
  507. X     node^.l := nn;
  508. X       END (* if empty tree*);
  509. X       INC(tree^.nbr);
  510. X     END insert;
  511. X
  512. X(*   *)
  513. X
  514. X  PROCEDURE delete(tree:T; item:splayItem.T);
  515. X     VAR l,r,nnn,nn,n,pnn:Tree;
  516. X         left,right:treeNode;
  517. X         fFound:BOOLEAN;
  518. X     i:CARDINAL;
  519. X     PROCEDURE replace(VAR p:Tree; n:Tree);
  520. X        VAR r,pr:Tree;
  521. X        BEGIN (* replace *)
  522. X           r:=n^.l;
  523. X       IF r=NIL THEN p:=n^.r;
  524. X       ELSE 
  525. X          IF r^.r=NIL THEN p:=r; p^.r:=n^.r;
  526. X          ELSE 
  527. X             WHILE r^.r#NIL DO DEC(r^.weight); pr:=r; r:=r^.r; END;
  528. X             pr^.r:=r^.l;
  529. X             r^.l:=n^.l; r^.r:=n^.r;
  530. X             p:=r;
  531. X          END;
  532. X       END (* if *);
  533. X       splayItem.destroy(n^.data);
  534. X       Storage.DEALLOCATE(n,SIZE(treeNode));
  535. X       DEC(tree^.nbr);
  536. X        END replace;
  537. X      PROCEDURE fixWeight(n:Tree);
  538. X    VAR nn:Tree;   
  539. X    BEGIN (* fixWeight *)
  540. X        n^.weight:=1;
  541. X        nn:=n^.r;
  542. X        IF nn#NIL THEN 
  543. X           nn^.weight:=1;
  544. X           IF nn^.l#NIL THEN INC(nn^.weight,nn^.l^.weight); END;
  545. X           IF nn^.r#NIL THEN INC(nn^.weight,nn^.r^.weight); END;
  546. X           INC(n^.weight,nn^.weight);
  547. X        END;
  548. X        nn:=n^.l;
  549. X        IF nn#NIL THEN 
  550. X           nn^.weight:=1;
  551. X           IF nn^.l#NIL THEN INC(nn^.weight,nn^.l^.weight); END;
  552. X           IF nn^.r#NIL THEN INC(nn^.weight,nn^.r^.weight); END;
  553. X           INC(n^.weight,nn^.weight); 
  554. X        END;
  555. X    END fixWeight;
  556. X    
  557. X     BEGIN (* delete *) 
  558. X        l:=SYSTEM.ADR(left); r:=SYSTEM.ADR(right);
  559. X    l^.l:=NIL; l^.r:=NIL;
  560. X    r^.l:=NIL; r^.r:=NIL;
  561. X        lp:=0;rp:=0;ls[0]:=l;rs[0]:=r;
  562. X        n := tree^.t;
  563. X    IF n=NIL THEN RETURN;
  564. X    ELSIF splayItem.cmp(n^.data,item)=0 THEN replace(tree^.t,n);
  565. X    ELSE
  566. X       LOOP
  567. X          IF l#ls[lp] THEN INC(lp);
  568. X            IF lp>stackSize THEN error.raise("Internal error splay(delete):\n");HALT;
  569. X            ELSE ls[lp]:=l; END;
  570. X          END;
  571. X          IF r#rs[rp] THEN INC(rp); 
  572. X            IF rp>stackSize THEN error.raise("Internal error/delete):\n");HALT;
  573. X            ELSE rs[rp]:=r; END;
  574. X          END;
  575. X       
  576. X          IF splayItem.cmp(item,n^.data)<0 THEN
  577. X             nn:=n^.l;
  578. X         IF nn=NIL THEN EXIT;
  579. X         ELSE 
  580. X            IF splayItem.cmp(item,nn^.data)=0 THEN 
  581. X               replace(n^.l,nn);
  582. X               EXIT;  
  583. X            ELSIF splayItem.cmp(item,nn^.data)<0 THEN 
  584. X               nnn:=nn^.l;
  585. X               IF nnn#NIL THEN
  586. X                     IF splayItem.cmp(item,nnn^.data)=0 THEN
  587. X                 replace(nn^.l,nnn);
  588. X                 r^.l:=n; r:=n; n:=nn;
  589. X                 EXIT;
  590. X              ELSE (* case III *) 
  591. X                 n^.l:=nn^.r;
  592. X                 r^.l:=nn; r:=nn; 
  593. X                 nn^.r:=n;
  594. X                 n:=nnn;
  595. X              END (* if *);
  596. X               ELSE (* nnn=NIL *)
  597. X                     r^.l:=n; r:=n; n:=nn;
  598. X              EXIT;
  599. X               END (* if nnn#NIL *);
  600. X            ELSE (* item > n^.data *)
  601. X               nnn:=nn^.r;
  602. X               IF nnn#NIL THEN
  603. X                  IF splayItem.cmp(item,nnn^.data)=0 THEN
  604. X                 replace(nn^.r,nnn);
  605. X                 r^.l:=n; r:=n; n:=nn;
  606. X                 EXIT;
  607. X              ELSE (* case V *)
  608. X                 l^.r:=nn; l:=nn;
  609. X                 r^.l:=n; r:=n;
  610. X                 n:=nnn;
  611. X              END (* if *);
  612. X               ELSE (* nnn=NIL *)
  613. X              r^.l:=n; r:=n; n:=nn;
  614. X              EXIT;
  615. X               END (* if nnn#NIL *);
  616. X            END (* if *);
  617. X         END (* if nn#NIL  *);
  618. X          ELSE (* item>n^.data *)
  619. X               nn:=n^.r;
  620. X         IF nn=NIL THEN EXIT;
  621. X         ELSE 
  622. X            IF splayItem.cmp(item,nn^.data)=0 THEN 
  623. X               replace(n^.r,nn);
  624. X               EXIT;  
  625. X            ELSIF splayItem.cmp(item,nn^.data)>0 THEN 
  626. X               nnn:=nn^.r;
  627. X               IF nnn#NIL THEN
  628. X                     IF splayItem.cmp(item,nnn^.data)=0 THEN
  629. X                 replace(nn^.r,nnn);
  630. X                 l^.r:=n; l:=n; n:=nn;
  631. X                 EXIT;
  632. X              ELSE (* case IV *)
  633. X                 n^.r:=nn^.l;
  634. X                 l^.r:=nn; l:=nn;
  635. X                 nn^.l:=n;
  636. X                 n:=nnn;
  637. X              END (* if *);
  638. X               ELSE (* nnn=NIL *)
  639. X              l^.r:=n; l:=n; n:=nn;
  640. X              EXIT;
  641. X               END (* if nnn#NIL *);
  642. X            ELSE (* item < n^.data *)
  643. X               nnn:=nn^.l;
  644. X               IF nnn#NIL THEN
  645. X                  IF splayItem.cmp(item,nnn^.data)=0 THEN
  646. X                 replace(nn^.l,nnn);
  647. X                 l^.r:=n; l:=n; n:=nn;
  648. X                 EXIT;
  649. X              ELSE (* case VI *)
  650. X                 l^.r:=n; l:=n;
  651. X                 r^.l:=nn; r:=nn;
  652. X                 n:=nnn;
  653. X              END (* if *);
  654. X               ELSE (* nnn=NIL *)
  655. X              l^.r:=n; l:=n; n:=nn;
  656. X              EXIT;
  657. X               END (* if nnn#NIL *);
  658. X            END (* if *);
  659. X         END (* if nn#nil *);
  660. X          END (* if *);
  661. X       END (* loop *);
  662. X       IF l#ls[lp] THEN INC(lp); ls[lp]:=l; END;
  663. X       IF r#rs[rp] THEN INC(rp); rs[rp]:=r; END; 
  664. X       l^.r:=n^.l; r^.l:=n^.r; 
  665. X       n^.l:=left.r; n^.r:=right.l;
  666. X       tree^.t:=n;
  667. X     (*
  668. X     ** Now, walk back up the left AND right built tree, i.e all nodes
  669. X     ** that are smaller (and bigger) than the node searched for, 
  670. X     ** and update all weights. This is done using an explicit stack ls
  671. X     ** and lr.
  672. X     *) 
  673. X          
  674. X       FOR i := lp TO 1 BY -1 DO
  675. X         fixWeight(ls[i]);
  676. X       END (* for *);
  677. X       FOR i := rp TO 1 BY -1 DO
  678. X         fixWeight(rs[i]);
  679. X       END (* for *); 
  680. X    END;
  681. X    IF tree^.t#NIL THEN fixWeight(tree^.t); END;
  682. X     END delete;
  683. X
  684. X
  685. X(*   *)
  686. X  PROCEDURE find(tree:T; item:splayItem.T;VAR found:splayItem.T): BOOLEAN;
  687. X     VAR l,r,nnn,nn,n:Tree;
  688. X         left,right:treeNode;
  689. X         fFound : BOOLEAN;
  690. X     i:CARDINAL;
  691. X     BEGIN (* find *)
  692. X        l:=SYSTEM.ADR(left); r:=SYSTEM.ADR(right);
  693. X    l^.l:=NIL; l^.r:=NIL;
  694. X    r^.l:=NIL; r^.r:=NIL;
  695. X    
  696. X    fFound:=FALSE;
  697. X        n := tree^.t;
  698. X    lp:=0;rp:=0;ls[0]:=l;rs[0]:=r;
  699. X    IF n=NIL THEN RETURN FALSE;
  700. X    ELSIF splayItem.cmp(n^.data,item)=0 THEN
  701. X       found:=n^.data; 
  702. X       RETURN TRUE;
  703. X    ELSE
  704. X       LOOP
  705. X          IF l#ls[lp] THEN INC(lp);
  706. X            IF lp>stackSize THEN error.raise("Internal error splay(find):\n");HALT;
  707. X            ELSE ls[lp]:=l; END;
  708. X          END;
  709. X          IF r#rs[rp] THEN INC(rp); 
  710. X            IF rp>stackSize THEN error.raise("Internal error splay(find):\n");HALT;
  711. X            ELSE rs[rp]:=r; END;
  712. X          END;
  713. X       
  714. X          IF splayItem.cmp(item,n^.data)=0 THEN
  715. X             found:=n^.data; fFound:=TRUE;
  716. X         EXIT;
  717. X          ELSIF splayItem.cmp(item,n^.data)<0 THEN
  718. X             nn:=n^.l;
  719. X         IF nn=NIL THEN EXIT;
  720. X         ELSE 
  721. X            IF splayItem.cmp(item,nn^.data)=0 THEN  (* case I   *)
  722. X               r^.l:=n; r:=n; n:=nn;
  723. X               found:=n^.data; fFound:=TRUE;
  724. X               EXIT;  
  725. X            ELSIF splayItem.cmp(item,nn^.data)<0 THEN 
  726. X               nnn:=nn^.l;
  727. X               IF nnn#NIL THEN                  (* case III *)
  728. X              n^.l:=nn^.r;
  729. X              r^.l:=nn; r:=nn; 
  730. X              nn^.r:=n; n:=nnn;
  731. X               ELSE (* nnn=NIL *)
  732. X                     r^.l:=n; r:=n; n:=nn;
  733. X              EXIT;
  734. X               END (* if nnn#NIL *);
  735. X            ELSE (* item > nn^.data *)
  736. X               nnn:=nn^.r;
  737. X               IF nnn#NIL THEN                  (* case V   *)
  738. X              l^.r:=nn; l:=nn;
  739. X              r^.l:=n; r:=n; n:=nnn;
  740. X               ELSE (* nnn=NIL *)
  741. X              r^.l:=n; r:=n; n:=nn;
  742. X              EXIT;
  743. X               END (* if nnn#NIL *);
  744. X            END (* if *);
  745. X         END (* if nn#NIL  *);
  746. X          ELSE (* item>n^.data *)
  747. X               nn:=n^.r;
  748. X         IF nn=NIL THEN EXIT;
  749. X         ELSE 
  750. X            IF splayItem.cmp(item,nn^.data)=0 THEN  (* case II  *)
  751. X               l^.r:=n; l:=n; n:=nn;
  752. X               found:=n^.data; fFound:=TRUE;
  753. X               EXIT;  
  754. X            ELSIF splayItem.cmp(item,nn^.data)>0 THEN 
  755. X               nnn:=nn^.r;
  756. X               IF nnn#NIL THEN                  (* case IV  *)
  757. X              n^.r:=nn^.l;
  758. X              l^.r:=nn; l:=nn;
  759. X              nn^.l:=n; n:=nnn;
  760. X               ELSE (* nnn=NIL *)
  761. X              l^.r:=n; l:=n; n:=nn;
  762. X              EXIT;
  763. X               END (* if nnn#NIL *);
  764. X            ELSE (* item < nn^.data *)
  765. X               nnn:=nn^.l;
  766. X               IF nnn#NIL THEN                  (* case VI  *)
  767. X              l^.r:=n; l:=n;
  768. X              r^.l:=nn; r:=nn; n:=nnn;
  769. X               ELSE (* nnn=NIL *)
  770. X              l^.r:=n; l:=n; n:=nn;
  771. X              EXIT;
  772. X               END (* if nnn#NIL *);
  773. X            END (* if cmp(...) *);
  774. X         END (* if nn=nil *);
  775. X          END (* if cmp(...) *);
  776. X       END (* loop *);
  777. X       IF l#ls[lp] THEN INC(lp); ls[lp]:=l; END;
  778. X       IF r#rs[rp] THEN INC(rp); rs[rp]:=r; END; 
  779. X       
  780. X       r^.l:=n^.r; l^.r:=n^.l; 
  781. X       n^.l:=left.r; n^.r:=right.l; 
  782. X       tree^.t:=n;
  783. X     (*
  784. X     ** Now, walk back up the left AND right built tree, i.e all nodes
  785. X     ** that are smaller (and bigger) than the node searched for, 
  786. X     ** and update all weights. This is done using an explicit stack ls
  787. X     ** and lr.
  788. X     *) 
  789. X       
  790. X       FOR i := lp TO 0 BY -1 DO
  791. X        n:=ls[i]; n^.weight:=1;
  792. X        nn:=n^.l;
  793. X        IF nn#NIL THEN 
  794. X           nn^.weight:=1;           
  795. X           IF nn^.l#NIL THEN nn^.weight:=nn^.weight+nn^.l^.weight; END;
  796. X           IF nn^.r#NIL THEN nn^.weight:=nn^.weight+nn^.r^.weight; END;
  797. X           n^.weight:=n^.weight+nn^.weight; 
  798. X        END;
  799. X        nn:=n^.r;
  800. X        IF nn#NIL THEN n^.weight:=n^.weight+nn^.weight; END; 
  801. X       END (* for *);
  802. X     
  803. X       FOR i := rp TO 0 BY -1 DO
  804. X         n:=rs[i]; n^.weight:=1;
  805. X         nn:=n^.r;
  806. X         IF nn#NIL THEN 
  807. X           nn^.weight:=1;
  808. X           IF nn^.l#NIL THEN nn^.weight:=nn^.weight+nn^.l^.weight; END;
  809. X           IF nn^.r#NIL THEN nn^.weight:=nn^.weight+nn^.r^.weight; END;
  810. X           n^.weight:=n^.weight+nn^.weight; 
  811. X         END;
  812. X         nn:=n^.l;
  813. X         IF nn#NIL THEN n^.weight:=n^.weight+nn^.weight; END;
  814. X       END (* for *); 
  815. X    END;
  816. X    RETURN fFound;      
  817. X     END find;
  818. X  
  819. X
  820. X  PROCEDURE getRank(tree:T; item:splayItem.T): CARDINAL;
  821. X     VAR t,p:Tree;rank:CARDINAL;
  822. X     BEGIN (* getRank *)
  823. X       t:=tree^.t;
  824. X       p:=NIL;
  825. X       rank:=1;
  826. X       LOOP 
  827. X         IF t = NIL THEN
  828. X           RETURN 0;
  829. X         ELSE 
  830. X           IF splayItem.cmp(t^.data,item)=0 THEN 
  831. X               IF t^.l # NIL THEN 
  832. X                  RETURN rank+t^.l^.weight;
  833. X               ELSE
  834. X                  RETURN rank;
  835. X               END;
  836. X           ELSIF splayItem.cmp(t^.data,item) > 0  THEN 
  837. X               p:=t;
  838. X               t := t^.l;
  839. X           ELSE
  840. X               IF t^.l#NIL THEN  
  841. X                  rank:=rank+t^.l^.weight+1;
  842. X               ELSE 
  843. X                  INC(rank);
  844. X               END;
  845. X               p:=t;
  846. X               t := t^.r
  847. X           END;
  848. X         END (* if *);
  849. X       END (* loop *);
  850. X     END getRank;
  851. X
  852. X  
  853. X   PROCEDURE getRankElement(tree:T; r:CARDINAL; VAR found:splayItem.T):BOOLEAN;
  854. X      VAR n:Tree;rank,weight:CARDINAL;
  855. X      BEGIN (* getRankElement *)
  856. X         n:=tree^.t;
  857. X     rank:=0;
  858. X     WHILE n#NIL DO
  859. X       IF n^.l#NIL THEN weight:=n^.l^.weight+1;
  860. X       ELSE weight:=1; END; 
  861. X       IF r=rank+weight THEN
  862. X         found:=n^.data;
  863. X         RETURN TRUE;
  864. X       ELSIF r<rank+weight THEN
  865. X         n:=n^.l;
  866. X       ELSE
  867. X         rank:=rank+weight;
  868. X         n:=n^.r; 
  869. X       END (* if *);
  870. X     END;
  871. X     RETURN FALSE;
  872. X      END getRankElement;
  873. X      
  874. X
  875. X  PROCEDURE mapIn(tree:T; f:auxFunc);
  876. X     PROCEDURE mI(t:Tree);
  877. X    BEGIN (* mI *)
  878. X      IF t # NIL THEN mI(t^.l); f(t^.data); mI(t^.r); END;
  879. X    END mI;
  880. X     BEGIN (* mapIn *)
  881. X       mI(tree^.t); 
  882. X     END mapIn;
  883. X
  884. X
  885. X  PROCEDURE mapPre(tree:T; f:auxFunc);
  886. X     PROCEDURE mPr(t:Tree);
  887. X    BEGIN (* mPr *)
  888. X      IF t # NIL THEN f(t^.data); mPr(t^.l); mPr(t^.r); END;
  889. X    END mPr;
  890. X     BEGIN (* mapPre *)
  891. X       mPr(tree^.t); 
  892. X     END mapPre;
  893. X
  894. X
  895. X  PROCEDURE mapPos(tree:T; f:auxFunc);
  896. X     PROCEDURE mPo(t:Tree);
  897. X    BEGIN (* mPo *)
  898. X      IF t # NIL THEN mPo(t^.l); mPo(t^.r); f(t^.data); END;
  899. X    END mPo;
  900. X     BEGIN (* mapPos *)
  901. X       mPo(tree^.t); 
  902. X     END mapPos;
  903. X
  904. XEND splay.
  905. X
  906. END_OF_FILE
  907.   if test 15974 -ne `wc -c <'splay.mod'`; then
  908.     echo shar: \"'splay.mod'\" unpacked with wrong size!
  909.   fi
  910.   # end of 'splay.mod'
  911. fi
  912. if test -f 'splayItem.def' -a "${1}" != "-c" ; then 
  913.   echo shar: Will not clobber existing file \"'splayItem.def'\"
  914. else
  915.   echo shar: Extracting \"'splayItem.def'\" \(505 characters\)
  916.   sed "s/^X//" >'splayItem.def' <<'END_OF_FILE'
  917. XDEFINITION MODULE splayItem;
  918. X(*
  919. X     Title:        
  920. X    Last Edit:    Sun Nov 22 12:31:05 1992
  921. X    Author:        Johan Persson at my9
  922. X
  923. X*)
  924. X  TYPE
  925. X     T = INTEGER;
  926. X
  927. X  PROCEDURE cmp(a:T; b:T): INTEGER;
  928. X  (* Returns:       cmp(a,b) = 0  => a=b
  929. X           cmp(a,b) = 1  => a>b
  930. X           cmp(a,b) = -1 => a<b
  931. X  *)
  932. X  
  933. X  PROCEDURE create(VAR a:T);
  934. X  (* Post: A new object has been created 
  935. X  *) 
  936. X  
  937. X  PROCEDURE destroy(VAR a:T);
  938. X  (* Pre: create(a)
  939. X     Post: All memory occupied by 'a' has been returned.
  940. X           a = NIL 
  941. X  *)
  942. X  
  943. XEND splayItem.
  944. END_OF_FILE
  945.   if test 505 -ne `wc -c <'splayItem.def'`; then
  946.     echo shar: \"'splayItem.def'\" unpacked with wrong size!
  947.   fi
  948.   # end of 'splayItem.def'
  949. fi
  950. if test -f 'splayItem.mod' -a "${1}" != "-c" ; then 
  951.   echo shar: Will not clobber existing file \"'splayItem.mod'\"
  952. else
  953.   echo shar: Extracting \"'splayItem.mod'\" \(447 characters\)
  954.   sed "s/^X//" >'splayItem.mod' <<'END_OF_FILE'
  955. X(*
  956. X    Title:        
  957. X    Last Edit:    Sun Nov 22 12:30:53 1992
  958. X    Author:        Johan Persson at my16
  959. X*)
  960. X
  961. XIMPLEMENTATION MODULE splayItem;
  962. X
  963. X  
  964. X  PROCEDURE cmp(a:T; b:T): INTEGER;
  965. X     BEGIN (* cmp *)
  966. X    IF a=b THEN RETURN 0;
  967. X    ELSIF a<b THEN RETURN -1;
  968. X    ELSE RETURN 1;
  969. X    END (* if *);
  970. X     END cmp;
  971. X
  972. X  PROCEDURE destroy(VAR a:T);
  973. X     BEGIN (* destroy *)
  974. X     END destroy;
  975. X     
  976. X  PROCEDURE create(VAR a:T);
  977. X     BEGIN (* create *)
  978. X     END create;
  979. X  
  980. X  
  981. X
  982. XEND splayItem.
  983. END_OF_FILE
  984.   if test 447 -ne `wc -c <'splayItem.mod'`; then
  985.     echo shar: \"'splayItem.mod'\" unpacked with wrong size!
  986.   fi
  987.   # end of 'splayItem.mod'
  988. fi
  989. if test -f 'splayTest.mod' -a "${1}" != "-c" ; then 
  990.   echo shar: Will not clobber existing file \"'splayTest.mod'\"
  991. else
  992.   echo shar: Extracting \"'splayTest.mod'\" \(4178 characters\)
  993.   sed "s/^X//" >'splayTest.mod' <<'END_OF_FILE'
  994. XMODULE splayTest; 
  995. X(*
  996. X    Title:        
  997. X    Last Edit:    Mon Dec 21 11:43:13 1992
  998. X    Author:        Johan Persson at my9
  999. X
  1000. X    SCCS:        %Z%%M%       %I%     %E%        
  1001. X
  1002. X*)
  1003. X
  1004. XIMPORT splay, splayItem, std, string, int, card, randomstrm;
  1005. X
  1006. XCONST 
  1007. X
  1008. X MaxC = 25000;
  1009. X MaxR = 25000.0;
  1010. X
  1011. X
  1012. XVAR t:splay.T;
  1013. X    i,r,rank,tests:CARDINAL;
  1014. X    tmp:splayItem.T;
  1015. X    bf:BOOLEAN;
  1016. X    v : ARRAY [1..MaxC] OF BOOLEAN;
  1017. X    rnd : randomstrm.Obj;
  1018. X    idx:CARDINAL;
  1019. X    
  1020. X   
  1021. XPROCEDURE printsplayItem(i:splayItem.T);
  1022. X   
  1023. X   BEGIN (* printsplayItem *)
  1024. X     int.write(std.out,i,0);
  1025. X     string.writef(std.out,",");   
  1026. X   END printsplayItem;
  1027. X
  1028. X
  1029. XPROCEDURE msg(s:ARRAY OF CHAR);
  1030. X   BEGIN (* msg *)
  1031. X     string.writef(std.out,s);
  1032. X   END msg;
  1033. X
  1034. XPROCEDURE testRank ();
  1035. X   VAR i,idx:CARDINAL;
  1036. X   BEGIN (* testRank *)
  1037. X     idx:=1;
  1038. X     FOR i := 1 TO MaxC DO
  1039. X        IF v[i] THEN
  1040. X          rank:=splay.getRank(t,i);
  1041. X          IF idx#rank THEN 
  1042. X            string.writef(std.out,"** ERROR IN RANK.\n");
  1043. X        string.writef(std.out," (i=");
  1044. X        card.write(std.out,i,0);
  1045. X        string.writef(std.out,")\n");
  1046. X        string.writef(std.out," rank=");
  1047. X        card.write(std.out,rank,0);
  1048. X        string.writef(std.out,"\n");
  1049. X        string.writef(std.out," idx=");
  1050. X        card.write(std.out,idx,0);
  1051. X        string.writef(std.out,"\n");
  1052. X        msg("Number OF tests: ");
  1053. X        card.write(std.out,tests,0);
  1054. X        string.writef(std.out,"\n");
  1055. X        splay.mapIn(t,printsplayItem);
  1056. X        HALT;
  1057. X      END;
  1058. X      INC(idx); 
  1059. X       ELSE
  1060. X     (* card.write(std.out,i,0);
  1061. X      msg(": F, ");*)
  1062. X        END;
  1063. X      END;
  1064. X   END testRank;
  1065. X
  1066. XBEGIN
  1067. X
  1068. Xmsg("Create the structure ...");
  1069. X
  1070. Xsplay.create(t);
  1071. X
  1072. Xmsg("done.\n");
  1073. X
  1074. Xmsg("Beginning with insertions\n");
  1075. X
  1076. XFOR i := 0 TO 255 DO
  1077. X  splay.insert(t,i);   
  1078. XEND (* for *);
  1079. X
  1080. Xmsg("Done with insertions\n");
  1081. X
  1082. XIF splay.find(t,13,tmp) THEN
  1083. X   msg("found 13 (tmp=");
  1084. X   int.write(std.out,tmp,0);
  1085. X   msg(") OK.\n");
  1086. X   splay.mapPre(t,printsplayItem);
  1087. X   msg("\n");
  1088. XELSE
  1089. X   msg("****** ERROR IN find routine!\n");
  1090. XEND (* if *);
  1091. X
  1092. XIF splay.find(t,18,tmp) THEN
  1093. X   msg("found 18 (tmp=");
  1094. X   int.write(std.out,tmp,0);
  1095. X   msg(") OK.\n");
  1096. X   splay.mapPre(t,printsplayItem);
  1097. X   msg("\n");
  1098. XELSE
  1099. X   msg("**** ERROR IN exist routine!\n");
  1100. XEND (* if *);
  1101. X
  1102. XIF splay.find(t,300,tmp) THEN
  1103. X   msg("ERROR IN exist routine!  ");
  1104. X   msg("found 300 (tmp=");
  1105. X   int.write(std.out,tmp,0);
  1106. X   msg(")\n");
  1107. XELSE
  1108. X   msg("Didn't find 300. OK.\n");
  1109. X   splay.mapPre(t,printsplayItem);
  1110. X   msg("\n");
  1111. XEND (* if *);
  1112. X
  1113. X
  1114. Xmsg("Print a sorted version ...\n");
  1115. X
  1116. Xsplay.mapIn(t,printsplayItem);
  1117. X
  1118. Xmsg("\n\n Print some rank's\n");
  1119. X
  1120. XIF splay.getRankElement(t,3,tmp) THEN 
  1121. X   msg("3=> "); int.write(std.out,tmp,0); msg("\n");
  1122. XELSE 
  1123. X   msg("ERROR didn't find rank 3\n\n");
  1124. XEND;
  1125. X
  1126. XIF splay.getRankElement(t,1,tmp) THEN 
  1127. X   msg("1=> "); int.write(std.out,tmp,0); msg("\n");
  1128. XELSE 
  1129. X   msg("ERROR didn't find rank 1\n\n");
  1130. XEND;
  1131. X
  1132. XIF splay.getRankElement(t,6,tmp) THEN 
  1133. X   msg("6=> "); int.write(std.out,tmp,0); msg("\n");
  1134. XELSE 
  1135. X   msg("ERROR didn't find rank 6\n\n");
  1136. XEND;
  1137. X
  1138. XIF splay.getRank(t,255)#256 THEN 
  1139. X   msg("**** ERROR IN getRank\n");
  1140. XELSE 
  1141. X   msg("\n 255 has rank 256\n");
  1142. XEND;
  1143. X
  1144. Xmsg("\n and now we delete som element");
  1145. X
  1146. Xmsg("\n 6 ..");
  1147. X
  1148. Xsplay.delete(t,6);
  1149. X
  1150. Xmsg("\n Print a sorted version ...\n");
  1151. X
  1152. Xsplay.mapIn(t,printsplayItem);
  1153. X
  1154. Xmsg("\n");
  1155. X
  1156. Xsplay.destroy(t);
  1157. X
  1158. Xmsg("\n Finished first part. Starting exhaustive test (hit Ctrl-C TO abort)\n");
  1159. X
  1160. X
  1161. Xsplay.create(t);
  1162. X
  1163. Xmsg("Beginning with insertions ... \n");
  1164. X
  1165. XFOR i := 1 TO MaxC  DO
  1166. X  splay.insert(t,i); 
  1167. X  v[i]:=TRUE;  
  1168. XEND (* for *);
  1169. X
  1170. Xmsg("done.\n");
  1171. X
  1172. XIF splay.find(t,MaxC DIV 2,tmp) THEN 
  1173. X  msg("Starting test: of insert... ");
  1174. X  testRank;
  1175. X  msg("done.\n Passed test 1.\n");
  1176. XELSE
  1177. X  msg("Failed 'find' test 1\n");
  1178. XEND;
  1179. X
  1180. Xmsg("Starting test sequence ...\n");
  1181. Xtests:=0;
  1182. Xrnd:=randomstrm.uniform(1.0, MaxR, 837 );
  1183. X
  1184. XLOOP
  1185. X  INC(tests);
  1186. X  IF tests=10000 THEN 
  1187. X     msg(".\n");
  1188. X     tests:=0;
  1189. X  END;
  1190. X  r:= TRUNC(randomstrm.next(rnd));
  1191. X  IF v[r] THEN
  1192. X     IF TRUNC(randomstrm.next(rnd)) > (MaxC DIV 2) THEN 
  1193. X       IF NOT splay.find(t,r,tmp) THEN 
  1194. X         msg("Error 'find'\n");
  1195. X       END;
  1196. X     ELSE
  1197. X       splay.delete(t,r);
  1198. X       v[r]:=FALSE;
  1199. X     END;
  1200. X     testRank;
  1201. X  ELSE
  1202. X     splay.insert(t,r);
  1203. X     v[r]:=TRUE;
  1204. X     testRank;
  1205. X  END (* if *);
  1206. XEND (* loop *);
  1207. X
  1208. X
  1209. XEND splayTest.
  1210. END_OF_FILE
  1211.   if test 4178 -ne `wc -c <'splayTest.mod'`; then
  1212.     echo shar: \"'splayTest.mod'\" unpacked with wrong size!
  1213.   fi
  1214.   # end of 'splayTest.mod'
  1215. fi
  1216. echo shar: End of archive 1 \(of 1\).
  1217. cp /dev/null ark1isdone
  1218. MISSING=""
  1219. for I in 1 ; do
  1220.     if test ! -f ark${I}isdone ; then
  1221.     MISSING="${MISSING} ${I}"
  1222.     fi
  1223. done
  1224. if test "${MISSING}" = "" ; then
  1225.     echo You have the archive.
  1226.     rm -f ark[1-9]isdone
  1227. else
  1228.     echo You still must unpack the following archives:
  1229.     echo "        " ${MISSING}
  1230. fi
  1231. exit 0
  1232. exit 0 # Just in case...
  1233.