home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol071 / tree4.pas < prev    next >
Pascal/Delphi Source File  |  1984-04-29  |  9KB  |  340 lines

  1. {       Pascal/Z compiler options               }
  2. {$C- <<<control-c keypress checking OFF>>>}
  3. {$M- <<<int mult & divd error checking OFF>>>}
  4. {$F- <<<floating point error checking OFF>>>}
  5.  
  6. PROGRAM BTREE;
  7. {
  8. Program title:    Binary Trees Demo
  9. Written by:
  10. Date written:    November 1981
  11.  
  12. Last edited:    11/20/81 rep
  13.  
  14. Pascal compiler: Pascal/Z vers 4.0, Ithaca Intersystems, Inc.
  15.  
  16. Summary:    Maintain a sorted list in a binary tree
  17.  
  18. Bibliography:
  19.   GROGONO, P.: Programming in PASCAL, Addison-Wesley Publishing Co.,
  20.     Reading, MA.
  21.   TENENBAUM, A. and AUGENSTEIN, M.: Data Structures Using Pascal,
  22.     Prentice-Hall, Englewood Cliffs, N.J. 07632
  23.   WIRTH, N.: Algorithms + Data Structures = Programs, Prentice-Hall,
  24.     Englewood Cliffs, N.J. 07632
  25. }
  26. CONST
  27.   default = 80;
  28.   vers    =  4; { PROGRAM VERSION NUMBER }
  29.  
  30. TYPE
  31.   alpha    = packed array [1..10] of char;
  32.   int      = integer;
  33.   str0     = string 0;
  34.   shorty   = string 40;
  35.   dstring  = string default;
  36.   str255   = string 255;
  37.  
  38.   PersonDetails = RECORD
  39.             Name,        { KEY FIELD }
  40.             Company,
  41.             address,
  42.             city,
  43.             state,
  44.             zip,
  45.             salary : shorty;
  46.                  END;
  47.  
  48.   apointer  = ^PERSON;
  49.  
  50.   PERSON = RECORD
  51.             details : PersonDetails;
  52.         Left,
  53.         Right  : apointer
  54.          END;
  55.  
  56.  
  57. VAR
  58.   bell        : char;
  59.   Command    : CHAR;
  60.   con_wanted,
  61.   tty_wanted    : boolean;
  62.   answer        : shorty;    { Console inputs here }
  63.  
  64.   KEY,                { Name field is the "KEY" field }
  65.   New_Salary,
  66.   New_Company,
  67.   New_address,
  68.   New_City,
  69.   New_State,
  70.   New_Zip        : shorty;
  71.  
  72.   STDOUT        : FILE OF PersonDetails;
  73.  
  74.   Employee    : apointer;
  75.  
  76.  
  77.  
  78. function length( x: str255 ): int; external;
  79.  
  80. function index( x,y: str255 ): int; external;
  81.  
  82. procedure setlength( var x:str0; y: int ); external;
  83.  
  84.  
  85. PROCEDURE InitTree( VAR Employee : apointer );
  86. {  initialize the tree to empty  }
  87. BEGIN
  88.   Employee := NIL
  89. END{of InitTree};
  90.  
  91.  
  92. PROCEDURE INSERT( VAR Employee : apointer;
  93.               key : shorty );
  94. { insert key into the tree. If it }
  95. { is there already then do nothing }
  96. BEGIN
  97.   IF Employee = NIL THEN BEGIN
  98.     NEW(Employee);
  99.     WITH Employee^, details DO BEGIN
  100.     Name    := key;
  101.     Salary  := New_Salary;
  102.     Company := New_Company;
  103.     address := New_address;
  104.     City    := New_City;
  105.     State   := New_State;
  106.     zip     := New_Zip;
  107.     left    := NIL;
  108.     right   := NIL
  109.     END{WITH}
  110.   END
  111.   ELSE IF key = Employee^.details.Name THEN
  112.     WRITELN( bell, key,' already in data file' )
  113.   ELSE IF key < Employee^.details.Name THEN
  114.     Insert( Employee^.left, key )
  115.   ELSE IF key > Employee^.details.Name THEN
  116.     Insert( Employee^.right, key )
  117. END{of INSERT};
  118.  
  119.  
  120. PROCEDURE DeleteLeftMost( VAR Employee : apointer;
  121.               VAR DeleteName : shorty );
  122. { delete the leftmost node in the tree and }
  123. {  returns its value in DeleteName       }
  124. BEGIN
  125.   IF Employee^.Left <> NIL THEN
  126.     DeleteLeftMost( Employee^.Left, DeleteName )
  127.   ELSE BEGIN
  128.     DeleteName := Employee^.details.Name;
  129.     Employee := Employee^.right
  130.   END
  131. END{of DeleteLeftMost};
  132.  
  133.  
  134. PROCEDURE DeleteRoot( VAR Employee : apointer );
  135. { deletes the root of the nonempty tree by replacing it  }
  136. { by its successor (or child) if it has only one, or     }
  137. { replacing its value by that of the leftmost descendant }
  138. { of the rightmost subtree.                 }
  139. VAR
  140.   DeletedName : shorty;
  141. BEGIN
  142.   IF Employee^.Left = NIL THEN
  143.     Employee := Employee^.right
  144.   ELSE IF Employee^.right = NIL THEN
  145.     Employee := Employee^.Left
  146.   ELSE BEGIN
  147.     DeleteLeftMost( Employee^.right, DeletedName );
  148.     Employee^.details.Name := DeletedName
  149.   END
  150. END{of DeleteRoot};
  151.  
  152.  
  153. PROCEDURE Delete( VAR Employee : apointer;
  154.               key : shorty );
  155. { delete key from the tree--if it is not }
  156. { in the tree, do nothing          }
  157. BEGIN
  158.   IF Employee = NIL THEN
  159.     WRITELN ( bell, key, ' not in data file' )
  160.   ELSE IF key = Employee^.details.Name THEN
  161.     DeleteRoot( Employee )
  162.   ELSE IF key < Employee^.details.Name THEN
  163.     Delete(Employee^.Left, key )
  164.   ELSE IF key > Employee^.details.Name THEN
  165.     Delete( Employee^.right, key )
  166. END;
  167.  
  168.  
  169. PROCEDURE DISPLAY( Employee: apointer );
  170. BEGIN
  171.   WITH Employee^.details do begin
  172.     writeln( Name );
  173.     if length( Company ) > 0 then writeln( Company );
  174.     if length( address ) > 0 then writeln( address );
  175.     writeln( City, ', ', State, ' ', Zip );
  176.     writeln
  177.   end
  178. END{of DISPLAY};
  179.  
  180.  
  181. PROCEDURE Preorder( Employee : apointer );
  182. {  prints data from left side of tree to right  } 
  183. BEGIN
  184.   IF Employee <> NIL THEN BEGIN
  185.     DISPLAY( Employee );    {visit the root}
  186.     Preorder( Employee^.Left );    {traverse the left subtree}
  187.     Preorder( Employee^.Right )    {traverse the right subtree}
  188.   END
  189. END{of preorder};
  190.  
  191.  
  192. PROCEDURE Inorder( Employee : apointer );
  193. {  prints data outer to inner of tree  }
  194. BEGIN
  195.   IF Employee <> NIL THEN BEGIN
  196.     Inorder( Employee^.Left );    {traverse the left subtree}
  197.     DISPLAY( Employee );    {visit the root}
  198.     Inorder( Employee^.Right )    {traverse the right subtree}
  199.   END
  200. END{of inorder};
  201.  
  202.  
  203. PROCEDURE Postorder( Employee : apointer );
  204. {  prints data from leaves first then branchs  }
  205. BEGIN
  206.   IF Employee <> NIL THEN BEGIN
  207.     Postorder( Employee^.Left );    {traverse the left subtree}
  208.     Postorder( Employee^.Right );    {traverse the right subtree}
  209.     DISPLAY( Employee );        {visit the root}
  210.   END
  211. END{of postorder};
  212.  
  213.  
  214. {****************************}
  215. {***   UTILITY ROUTINES   ***}
  216. {****************************}
  217.  
  218.  
  219. PROCEDURE SIGNON;
  220. VAR    IX : 1..24;
  221. BEGIN
  222.   FOR IX:=1 TO 24 DO WRITELN;
  223.   WRITELN( ' ':15, 'NAME AND ADDRESS ENTRY PROGRAM Version #', vers );
  224.   FOR IX:=1 TO 4 DO WRITELN;
  225. {    SIGNON TEXT GOES HERE    }
  226. END{of SIGNON};
  227.  
  228.  
  229. PROCEDURE MENU;
  230. BEGIN
  231.   WRITELN;
  232.   WRITELN;
  233.   WRITELN( ' ':12, '1  -  INSERT MODE' );
  234.   WRITELN( ' ':12, '2  -  DELETE MODE' );
  235.   WRITELN( ' ':12, '3  -  DISPLAY MODE' );
  236.   WRITELN( ' ':12, '9  -  TERMINATE' );
  237.   WRITELN;
  238.   CASE Command OF
  239.    '1': WRITELN( 'MODE=INSERT' );
  240.    '2': WRITELN( 'MODE=DELETE' );
  241.    '3': WRITELN( 'MODE=DISPLAY' );
  242.   ELSE: WRITELN
  243.   END{CASE}
  244. END{of MENU};
  245.  
  246.  
  247. FUNCTION toupper( ch: CHAR ): CHAR;
  248. BEGIN
  249.   IF ( 'a'<=ch ) AND ( ch<='z' ) THEN ch := CHR(ORD(ch) - 32);
  250.   toupper := ch
  251. END{of toupper};
  252.  
  253.  
  254. PROCEDURE INPUT( txt: dstring; VAR answer: shorty );
  255. BEGIN
  256.   WRITE( txt );
  257.   READLN( answer );
  258. END{of INPUT};
  259.  
  260.  
  261. PROCEDURE LIST;
  262. VAR    ch : CHAR;
  263.     OUTPUT : TEXT;
  264. BEGIN
  265.   WRITELN( 'Output to C(onsole or P(rinter? ' );
  266.   readln( ch );
  267.   con_wanted := ( toupper(ch)='C' );
  268.   tty_wanted := ( toupper(ch)='P' );
  269.   { one or the other but not both }
  270.   if tty_wanted then con_wanted := false;
  271.   if NOT (con_wanted OR tty_wanted) then
  272.     { listing := false }
  273.   else begin
  274.     { listing := true; }
  275.     if con_wanted then REWRITE( 'CON:', OUTPUT );
  276.     if tty_wanted then REWRITE( 'LST:', OUTPUT );
  277.   end;
  278.   WRITELN; WRITELN;
  279.   Inorder( Employee );
  280.   if con_wanted then begin
  281.     writeln;
  282.     WRITE( bell, 'PRESS RETURN TO CONTINUE ' );
  283.     READLN( ch );
  284.   end
  285. END{of LIST}{ CLOSE( OUTPUT ); };
  286.   
  287.   
  288.  
  289.  
  290. BEGIN{ MAIN PROGRAM BLOCK }
  291.   InitTree( Employee );
  292.   bell := chr(7);
  293.   Command := ' ';
  294.   SIGNON;
  295.   MENU;
  296.   INPUT( 'COMMAND: ', answer );
  297.   Command := toupper( answer[1] );
  298.   WHILE Command <> '9' DO BEGIN
  299.     IF Command IN ['1','2','3'] THEN BEGIN
  300.       WRITELN;
  301.       CASE Command  OF
  302.         '1': begin { INSERT MODE }
  303.          REPEAT
  304.         writeln( 'ENTER:' );
  305.         INPUT('1 - NAME <Key field>               !', key );
  306.         INPUT('2 - Salary amount <12000>          !', New_Salary );
  307.         input('3 - Company Name <address line 1>  !', New_Company );
  308.         input('4 - Address line 2                 !', New_address );
  309.         input('5 - City                           !', New_City );
  310.         input('6 - State <e.g. MD>                !', New_State );
  311.         input('7 - Zip Code                       !', New_Zip );
  312.         writeln;
  313.         write( 'DATA OK? ' );
  314.         readln( answer );
  315.           UNTIL toupper(answer[1])<>'N';
  316.           INSERT( Employee,key );
  317.          end;
  318.  
  319.         '2': begin { DELETE MODE }
  320.          REPEAT
  321.            INPUT( 'Enter NAME <Key field>      --> ',key );
  322.            writeln;
  323.            writeln( 'Deleting > ', key );
  324.            write( 'OK? ' );
  325.            readln( answer );
  326.          UNTIL toupper(answer[1])<>'N';
  327.          Delete( Employee,key );
  328.          end;
  329.  
  330.     '3': begin { LIST MODE }
  331.            LIST;
  332.          end
  333.       END{CASE}
  334.     END{IF};
  335.     MENU;
  336.     INPUT( 'COMMAND: ', answer );
  337.     Command := toupper( answer[1] );
  338.   END{WHILE Command <> '9'}
  339. END{of PROGRAM BTREE}.
  340.