home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 91 / af091a.adf / af91a3.lzx / prgs / Turtle / bst.b < prev    next >
Text File  |  2019-01-20  |  7KB  |  355 lines

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