home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d9xx / d969 / ace.lha / ACE / ACE-2.0.lha / PRGS.lha / Turtle / bst.b < prev    next >
Text File  |  1994-01-10  |  7KB  |  352 lines

  1. {A program that implements the Binary Search Tree operations 
  2.  from the text by Helman/Veroff/Carrano 
  3.  
  4.  Pascal version modified by David Benn, May 3rd 1993
  5.  
  6.  Rewritten (and extended) in ACE BASIC for the Amiga, 
  7.  June 19th,21st,22nd,30th, 
  8.  July 3rd 1993}
  9.  
  10. const PUBLIC=2
  11. const nil=0&
  12. const true=-1&,false=0&
  13. const down=0,lt=1,rt=2
  14. const fast=1,slow=2
  15. const moment=0.75
  16.  
  17. struct node
  18.   single  item
  19.   longint lchild
  20.   longint rchild
  21. end struct
  22.  
  23. declare  struct node *t
  24. longint  opt,finished
  25. shortint speed
  26.  
  27. SUB prepare_for_output
  28.     window output 2
  29.     locate 14,1
  30.     for i%=1 to 70:print " ";:next
  31.     locate csrlin,1
  32. END SUB
  33.  
  34. SUB Leftmost(ADDRESS paddr,ADDRESS itemaddr)
  35. declare struct node *p
  36. declare struct node *delnode
  37.  
  38.     p = *&paddr
  39.     if p <> nil then
  40.         if p->lchild = nil then
  41.             *!itemaddr := p->item
  42.             delnode = p
  43.             p = p->rchild
  44.             *&paddr := p
  45.         else
  46.             Leftmost(@p->lchild,itemaddr)
  47.         end if
  48.     end if
  49. END SUB
  50.  
  51. SUB Delitem(ADDRESS delptraddr)
  52. declare struct node *delptr
  53. declare struct node *p
  54. single  replitem
  55.  
  56.     delptr = *&delptraddr
  57.     if delptr <> nil then
  58.         if (delptr->lchild = nil) and (delptr->rchild = nil) then
  59.             {leaf}
  60.             delptr = nil
  61.             *&delptraddr := delptr
  62.         else 
  63.             if delptr->lchild = nil then
  64.                 {node with right child}
  65.                 p = delptr
  66.                 delptr = delptr->rchild
  67.                 *&delptraddr := delptr
  68.             else 
  69.                 if delptr->rchild = nil then
  70.                     {node with left child}
  71.                           p = delptr
  72.                     delptr = delptr->lchild
  73.                     *&delptraddr := delptr
  74.                 else
  75.                     {node with two children}
  76.                     Leftmost(@delptr->rchild,@replitem)
  77.                     delptr->item = replitem
  78.                 end if
  79.             end if
  80.         end if
  81.     end if
  82. END SUB
  83.  
  84. SUB Del(ADDRESS taddr,keyval)
  85. declare struct node *t
  86.     t = *&taddr
  87.     if T <> nil then
  88.         if keyval = T->item then
  89.             Delitem(taddr)
  90.         else 
  91.             if keyval < T->item then
  92.                 Del(@T->lchild,keyval)
  93.             else
  94.                 Del(@t->rchild,keyval)
  95.             end if
  96.         end if
  97.     end if
  98. END SUB
  99.  
  100. SUB DeleteItem(ADDRESS taddr)
  101.     input "Enter item: ",item
  102.     Del(taddr,item)
  103. END SUB
  104.  
  105. SUB Insert(ADDRESS taddr,newitem)
  106. declare struct node *t
  107.     t = *&taddr
  108.     if T = nil then
  109.         T = Alloc(sizeof(node),PUBLIC)
  110.         T->item = newitem
  111.         T->lchild = nil
  112.         T->rchild = nil
  113.         *&taddr := t
  114.     else 
  115.         if newitem < T->item then       
  116.             Insert(@T->lchild, newitem) 
  117.         else
  118.             Insert(@T->rchild, newitem)  
  119.         end if
  120.     end if
  121. END SUB
  122.  
  123. SUB InTree(ADDRESS taddr,single item)
  124. '..determine whether a value exists in the tree
  125. declare struct node *t
  126.     t = *&taddr
  127.     if t = nil then
  128.         InTree = false
  129.     else
  130.         if t->item = item then
  131.             InTree = true
  132.         else
  133.             if item < t->item then
  134.                 InTree(@t->lchild,item)
  135.             else
  136.                 InTree(@t->rchild,item)
  137.             end if
  138.         end if
  139.     end if        
  140. END SUB
  141.  
  142. SUB InsertItem(ADDRESS taddr)
  143.     input "Enter Item: ",item
  144.     if not InTree(taddr,item) then call Insert(taddr,item)    
  145. END SUB
  146.  
  147. SUB Traverse(ADDRESS taddr,shortint order)
  148. '..preorder,inorder or postorder traversal
  149. declare struct node *t
  150.     t = taddr
  151.     if t <> nil then
  152.         if order=1 then print t->item;
  153.         Traverse(t->lchild,order)
  154.         if order=2 then print t->item;
  155.         Traverse(t->rchild,order)
  156.         if order=3 then print t->item;
  157.     end if
  158. END SUB
  159.  
  160. SUB ShowNodes(ADDRESS taddr)
  161.     repeat
  162.       input "1=preorder  2=inorder  3=postorder ",order
  163.     until order>=1 and order<=3
  164.     prepare_for_output
  165.     Traverse(taddr,order)
  166.     window output 1
  167. END SUB
  168.  
  169. SUB GraphTree(ADDRESS taddr)
  170. '..postorder traversal showing tree structure
  171. declare struct node *t
  172. shared  speed
  173.     t = taddr
  174.     if T <> nil then
  175.         '..pause?
  176.         if speed=slow and t->lchild then 
  177.           time0=timer
  178.           while timer < time0+moment:wend
  179.         end if
  180.  
  181.         {left subtree}
  182.         setheading 135
  183.         if t->lchild then pendown:forward 20
  184.         GraphTree(T->lchild)
  185.         setheading 135
  186.         if t->lchild then penup:back 20 
  187.  
  188.         '..pause?
  189.         if speed=slow and t->rchild then 
  190.           time0=timer
  191.           while timer < time0+moment:wend
  192.         end if
  193.  
  194.         {right subtree}
  195.         setheading 45
  196.         if t->rchild then pendown:forward 20
  197.         GraphTree(T->rchild)
  198.         setheading 45
  199.         if t->rchild then penup:back 20
  200.  
  201.         '..pause?
  202.         if speed=slow then 
  203.           time0=timer
  204.           while timer < time0+moment:wend
  205.         end if
  206.  
  207.         {visit node}
  208.         num$=str$(T->item)
  209.         if sgn(T->item) <> -1 then num$=right$(num$,len(num$)-1)
  210.         '..position number centrally
  211.         halfnumlen%=len(num$)\2
  212.         penup
  213.         setxy xcor-halfnumlen%*8,ycor 
  214.         color 3
  215.         prints num$
  216.         color 2
  217.         setxy xcor+halfnumlen%*8,ycor
  218.         pendown
  219.     end if
  220.  
  221. END SUB                                          
  222.  
  223. SUB ShowTree(ADDRESS t)
  224. shared speed
  225.     window output 2
  226.     color 2,1
  227.     cls
  228.     setheading 90
  229.     penup
  230.     setxy 320,20
  231.     pendown
  232.     GraphTree(t)
  233.     window output 1
  234. END SUB
  235.  
  236. SUB TreeDisplaySpeed
  237. shared speed
  238.     repeat
  239.        input "1=fast  2=slow ",speed
  240.     until speed=fast or speed=slow
  241. END SUB
  242.  
  243. SUB kill_tree(ADDRESS t)
  244. ' make tree empty
  245.     *&t := nil
  246. END SUB
  247.  
  248. SUB max(x,y)
  249.     if x > y then
  250.         max = x
  251.     else
  252.         max = y
  253.     end if
  254. END SUB
  255.  
  256. SUB height(ADDRESS taddr)
  257. ' recursively determine height of tree
  258. declare struct node *t
  259.     t = taddr
  260.     if t <> nil then
  261.         height = max(height(t->lchild), height(t->rchild)) + 1
  262.     else
  263.         height = 0
  264.     end if
  265. END SUB
  266.  
  267. SUB maxitem(ADDRESS taddr)
  268. ' return maximum item in tree (rightmost node)
  269. declare struct node *t
  270.   t = taddr
  271.   if t = nil then
  272.      maxitem = 0
  273.   else
  274.      if t->rchild = nil then
  275.         maxitem = t->item
  276.      else
  277.         maxitem = maxitem(t->rchild)
  278.      end if
  279.   end if 
  280. END SUB
  281.  
  282. SUB nodes(ADDRESS taddr)
  283. ' return no. of nodes in tree
  284. declare struct node *t
  285.   t = taddr
  286.   if t <> nil then
  287.     nodes = nodes(t->lchild) + nodes(t->rchild) + 1
  288.   else
  289.      nodes = 0
  290.   end if
  291. END SUB
  292.  
  293. SUB SelectMenu(ADDRESS opt)
  294.     repeat
  295.     CLS
  296.     print "1.  Insert node"
  297.     print "2.  Delete node"               
  298.     print "3.  Print node values
  299.     print "4.  Show height of tree"
  300.     print "5.  Find maximum value"
  301.     print "6.  Count nodes in tree"
  302.     print "7.  Delete all nodes"
  303.     print "8.  Change tree display speed"
  304.         print "0.  Quit"
  305.         input "Make choice (0..8) ",choice
  306.     until choice >= 0 and choice <= 8
  307.     *&opt:=choice
  308. END SUB
  309.  
  310. SUB DoOption(longint opt,ADDRESS taddr,longint finished)
  311. declare struct node *t
  312. shared  speed
  313.       t = *&taddr
  314.       if opt>=4 and opt<=6 then call prepare_for_output
  315.       CASE 
  316.         opt=1  : InsertItem(@t)
  317.         opt=2  : DeleteItem(@t)
  318.         opt=3  : ShowNodes(t)
  319.         opt=4  : print "Height of tree is";height(t)
  320.         opt=5  : print "Maximum item is";maxitem(t)
  321.         opt=6  : print "Number of nodes in tree is";nodes(t)
  322.         opt=7  : kill_tree(@t)
  323.         opt=8  : TreeDisplaySpeed
  324.         opt=0  : *&finished := true
  325.       END CASE
  326.       if opt>=4 and opt<=6 then window output 1
  327.       if opt=1 or opt=2 or opt=7 then call ShowTree(t)
  328.       *&taddr := t
  329. END SUB
  330.  
  331. {main}
  332. window 2,"BST Output",(0,0)-(640,150)
  333. color 2,1
  334. cls
  335. window 1,"BST",(0,150)-(640,255)
  336. color 1
  337.  
  338. {create empty tree}
  339. t=nil
  340.  
  341. speed=fast
  342. finished=false
  343.  
  344. repeat
  345.   SelectMenu(@opt)
  346.   DoOption(opt,@t,@finished)
  347. until finished
  348.  
  349. kill_tree(@t)
  350. window close 1
  351. window close 2
  352.