home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / cdactual / demobin / share / program / Pascal / BFTGPH.ZIP / GRAPH.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-09-09  |  15.8 KB  |  398 lines

  1. Unit Graph;
  2.  
  3. (***************************************************************************)
  4. (*   Name: Graph                                                           *)
  5. (*   Written by: William Hobday                                            *)
  6. (*   Last Modified: September 6, 1991                                      *)
  7. (*                                                                         *)
  8. (*   Description:   This unit is an multilist implementation of a digraph. *)
  9. (*   Each header node contains two lists: one conatining the arcs          *)
  10. (*   emanating from the vertex, and the other terminating at that vertex.  *)
  11. (*   The unit consists of the following documented procedures and          *)
  12. (*   functions:                                                            *)
  13. (*                        NewGraph : Graph                                 *)
  14. (*                        NewVrtx( graph,name ) : vrtx                     *)
  15. (*                        FirstSuccessor( name ) : name                    *)
  16. (*                        NextSuccessor( name,name ) : name                *)
  17. (*                        Adjacent( vrtx,vrtx ) : boolean                  *)
  18. (*                        ArcWeight( vrtx,vrtx ) : weight                  *)
  19. (*                        WtdJoin( vrtx,vrtx,weight )                      *)
  20. (*                        RemoveArc( vrtx,vrtx )                           *)
  21. (*                        PrintGraph( graph )                              *)
  22. (*                        PrintArc( vrtx,vrtx )                            *)
  23. (*                                                                         *)
  24. (***************************************************************************)
  25.  
  26. Interface
  27.  
  28. type  Vertex = ^Vertexpointer;
  29.       Arc = ^Arcpointer;
  30.  
  31.       Arcpointer = record
  32.             Weight: integer;
  33.             Vertex1,
  34.             Vertex2: char;
  35.             Emanate,
  36.             Terminate: Arc
  37.          end;
  38.  
  39.       Vertexpointer = record
  40.             Name: char;
  41.             Emanate,
  42.             Terminate: Arc;
  43.             Next: Vertex;
  44.             Visited : boolean
  45.          end;
  46.  
  47.  
  48. Function NewGraph : Vertex;
  49. Function NewVrtx( var G : Vertex; Name: Char ): Vertex;
  50. Function FirstSuccessor( G : Vertex; Name : char ) : char;
  51. Function NextSuccessor( G : Vertex; Name : char; Successor : char ) : char;
  52. Function GetVertex ( G : Vertex; Name : char ) : Vertex;
  53. Function Adjacent( V1,V2 : Vertex ): boolean;
  54. Function ArcWeight( V1,V2 : Vertex ): integer;
  55. Procedure WtdJoin( V1,V2 : Vertex; Weight : integer );
  56. Procedure RemoveArc( var V1,V2 : Vertex );
  57. Procedure PrintGraph( G : Vertex );
  58. Procedure PrintArc( V1,V2 : Vertex );
  59.  
  60.  
  61. Implementation
  62.  
  63. (***************************************************************************)
  64. (*   Name: NewGraph                                                        *)
  65. (*                                                                         *)
  66. (*   Purposse: This Function returns a pointer to a new empty graph        *)
  67. (*   Input: None                                                           *)
  68. (*   Ouput: A pointer to a new graph                                       *)
  69. (***************************************************************************)
  70.  
  71. Function NewGraph : Vertex;
  72.  
  73. begin
  74.    NewGraph := nil
  75. end;
  76.  
  77.  
  78.  
  79. (***************************************************************************)
  80. (*   Name: NewVertex                                                       *)
  81. (*                                                                         *)
  82. (*   Purpose: Adds a new unconnected vertex to the graph                   *)
  83. (*   Uses: NewV - New vertex to be created                                 *)
  84. (*         Temp - Used to search for end of list                           *)
  85. (*   Input: G - Pointer to Graph                                           *)
  86. (*          Name - Name of new vertex                                      *)
  87. (*   Output: Pointer to newly created vertex                               *)
  88. (***************************************************************************)
  89.  
  90. Function NewVrtx( var G : Vertex; Name : char ) : Vertex;
  91.  
  92. var NewV,Temp: Vertex;
  93.  
  94. begin
  95.    new( NewV );
  96.    NewV^.Name := Name;
  97.    NewV^.Emanate := nil;
  98.    NewV^.Terminate := nil;
  99.    NewV^.Next := nil;
  100.    NewV^.Visited := false;
  101.    if G = nil
  102.       then G := NewV
  103.       else begin
  104.               Temp := G;
  105.               while Temp^.Next <> nil do
  106.                  Temp := Temp^.Next;
  107.               Temp^.Next := NewV
  108.            end;
  109.    NewVrtx := NewV
  110. end;
  111.  
  112.  
  113.  
  114. (***************************************************************************)
  115. (*   Name: GetVertex                                                       *)
  116. (*                                                                         *)
  117. (*   Purpose: Given a graph and a vertex name it returns a pointer to the  *)
  118. (*            vertex. Returns nil if vvertex doesn't exist.                *)
  119. (*   Input: G - the graph                                                  *)
  120. (*          Name - Name of vertex to find                                  *)
  121. (*   Output: pointer to vertex found                                       *)
  122. (***************************************************************************)
  123.  
  124. Function GetVertex( G : Vertex; Name : char) : Vertex;
  125.  
  126. begin
  127.    while ( G <> nil ) and ( G^.Name <> Name ) do
  128.       G := G^.Next;
  129.    GetVertex := G
  130. end;
  131.  
  132.  
  133.  
  134. (***************************************************************************)
  135. (*   Name: First Successor                                                 *)
  136. (*                                                                         *)
  137. (*   Purpose: Returns the first successor of the given vertex if it exists *)
  138. (*   otherwise it returns a nul(ASCII 0).                                  *)
  139. (*   Input: Name - Name of vertex from which the 1st successor is taken    *)
  140. (*   Output: FirstSuccessor - name to the 1st successor of vertex          *)
  141. (***************************************************************************)
  142.  
  143. Function FirstSuccessor ( G : Vertex; Name : char ) : char;
  144.  
  145. var V : Vertex;
  146.  
  147. begin
  148.    V := GetVertex( G,Name );
  149.    if V = nil
  150.       then FirstSuccessor := #0
  151.       else if V^.Emanate = nil
  152.               then FirstSuccessor := #0
  153.               else FirstSuccessor := V^.Emanate^.Vertex2
  154. end;
  155.  
  156.  
  157.  
  158. (***************************************************************************)
  159. (*   Name: NextSuccessor                                                   *)
  160. (*                                                                         *)
  161. (*   Purpose: Given a vertex and a successor, this returns the next        *)
  162. (*            successor.  Returns the first successor if input parameters  *)
  163. (*            are identical.  Returns nul if does not exist.               *)
  164. (*   Input: G - pointer to list of vertices                                *)
  165. (*          V - Name of vertex from which to find next successor           *)
  166. (*          Name - Name of vertex next successor is to follow              *)
  167. (*   Output: NextSuccessor - Name of the next successor                    *)
  168. (***************************************************************************)
  169.  
  170. Function NextSuccessor( G : Vertex; Name : char; Successor : char ) : char;
  171.  
  172. var TempArc : Arc;
  173.     V : Vertex;
  174.  
  175. begin
  176.    V := GetVertex( G,Name );
  177.    if v <> nil
  178.       then if V^.Name = Successor
  179.               then NextSuccessor := FirstSuccessor( G,Successor )
  180.               else begin
  181.                       TempArc := V^.Emanate;
  182.                       while ( TempArc^.Vertex2 <> Successor ) and ( TempArc <> nil ) do
  183.                          TempArc :=  TempArc^.Emanate;
  184.                       if TempArc = nil
  185.                          then NextSuccessor := #0
  186.                          else if TempArc^.Emanate <> nil
  187.                                  then NextSuccessor := TempArc^.Emanate^.Vertex2
  188.                                  else NextSuccessor := #0
  189.                    end
  190.       else NextSuccessor := #0
  191. end;
  192.  
  193.  
  194.  
  195. (***************************************************************************)
  196. (*   Name: Adjacent                                                        *)
  197. (*                                                                         *)
  198. (*   Purpose: Boolean function which returns true if given vertices are    *)
  199. (*            adjacent.                                                    *)
  200. (*   Input: V1,V2 - Vertices to check for arc                              *)
  201. (*   Output: Adjacent - Result of function                                 *)
  202. (***************************************************************************)
  203.  
  204. Function Adjacent( V1,V2 : Vertex ) : boolean;
  205.  
  206. var TempArc : Arc;
  207.  
  208. begin
  209.    if ( V1^.Emanate = nil )  or ( V2^.Emanate = nil ) or ( V1 = nil ) or ( v2 =nil)
  210.       then Adjacent := false
  211.       else begin
  212.               TempArc := V1^.Emanate;
  213.               while (TempArc <> nil) and (V2^.Name <> TempArc^.Vertex2) do
  214.                  TempArc := TempArc^.Emanate;
  215.               if TempArc^.Vertex2 = V2^.Name
  216.                  then Adjacent := true
  217.                  else Adjacent := false
  218.            end;
  219. end;
  220.  
  221.  
  222.  
  223. (***************************************************************************)
  224. (*   Name: ArcWeight                                                       *)
  225. (*                                                                         *)
  226. (*   Purpose: Returns the weight of the arc between V1 and V2 providing    *)
  227. (*            that it exists.  Returns a Zero otherwise.                   *)
  228. (*   Input: V1,V2 - vertices to check for arc                              *)
  229. (*   Output: ArcWeight - the weight of the arc if it exists                *)
  230. (***************************************************************************)
  231.  
  232. Function ArcWeight( V1,V2 : Vertex ) : integer;
  233.  
  234. var TempV : Arc;
  235.  
  236. begin
  237.    if ( V1^.Emanate = nil ) or ( V2^.Terminate = nil ) or ( not Adjacent( V1,V2 ) )
  238.       then ArcWeight := 0
  239.       else begin
  240.               TempV := V1^.Emanate;
  241.               while (V2^.Name <> TempV^.Vertex2) do
  242.                  TempV := TempV^.Emanate;
  243.               ArcWeight := TempV^.Weight
  244.            end;
  245. end;
  246.  
  247.  
  248.  
  249. (***************************************************************************)
  250. (*   Name: WtdJoin                                                         *)
  251. (*                                                                         *)
  252. (*   Purpose: Creates a weighted arc between V1 and V2 of weight Weight    *)
  253. (*   Input: V1,V2 - Vertices to connect                                    *)
  254. (*          Weight - the weight of the new arc                             *)
  255. (*   Output: None                                                          *)
  256. (***************************************************************************)
  257.  
  258. Procedure WtdJoin( V1,V2 : Vertex; Weight : Integer );
  259.  
  260. var NewArc, Temp : Arc;
  261.  
  262. begin
  263.    if not Adjacent( V1,V2 )
  264.       then begin
  265.               New( NewArc );
  266.               NewArc^.Weight := Weight;
  267.               NewArc^.Vertex1 := V1^.Name;
  268.               NewArc^.Vertex2 := V2^.Name;
  269.               NewArc^.Emanate := nil;
  270.               NewArc^.Terminate := nil;
  271.               Temp := V1^.Emanate;
  272.               if Temp = nil
  273.                  then V1^.Emanate := NewArc
  274.                  else begin
  275.                          while Temp^.Emanate <> nil do
  276.                             Temp := Temp^.Emanate;
  277.                          Temp^.Emanate := NewArc;
  278.                       end;
  279.               Temp := V2^.Terminate;
  280.               if Temp = nil
  281.                  then V2^.Terminate := NewArc
  282.                  else begin
  283.                          while Temp^.Terminate <> nil do
  284.                             Temp := Temp^.Terminate;
  285.                          Temp^.Terminate := NewArc;
  286.                       end
  287.            end
  288. end;
  289.  
  290.  
  291.  
  292. (***************************************************************************)
  293. (*   Name: RemoveArc                                                       *)
  294. (*                                                                         *)
  295. (*   Purpose: Removes the Arc from V1 to V2 if it exists                   *)
  296. (*   Input: V1,V2 - Vertices of arc to be removed                          *)
  297. (*   Output: None                                                          *)
  298. (***************************************************************************)
  299.  
  300. Procedure RemoveArc( var V1,V2 : Vertex );
  301.  
  302. var Temp,Temp2 : Arc;
  303.  
  304. begin
  305.    if Adjacent( V1,V2 )
  306.       then begin
  307.               Temp := V1^.Emanate;
  308.               if Temp^.Vertex2 = V2^.Name
  309.                  then V1^.Emanate := Temp^.Emanate
  310.                  else begin
  311.                          while Temp^.Emanate^.Vertex2 <> V2^.Name do
  312.                             Temp := Temp^.Emanate;
  313.                          Temp2 := Temp^.Emanate;
  314.                          Temp^.Emanate := Temp2^.Emanate
  315.                       end;
  316.               Temp := V2^.Terminate;
  317.               if Temp^.Vertex1 = V1^.Name
  318.                  then V2^.Terminate := Temp^.Terminate
  319.                  else begin
  320.                          while Temp^.Terminate^.Vertex1 <> V1^.Name do
  321.                             Temp := Temp^.Terminate;
  322.                          Temp2 := Temp^.Terminate;
  323.                          Temp^.Terminate := Temp2^.Terminate
  324.                       end
  325.            end
  326. end;
  327.  
  328.  
  329.  
  330. (***************************************************************************)
  331. (*   Name: PrintGraph                                                      *)
  332. (*                                                                         *)
  333. (*   Purpose: Prints an adjacency matrix for the graph                     *)
  334. (*   Input: G - First Vertex in linked vertex list of graph                *)
  335. (*   Output: Copy of the adjacency matrix for the graph                    *)
  336. (***************************************************************************)
  337.  
  338. Procedure PrintGraph( G: Vertex );
  339.  
  340. var Temp,Temp2 : Vertex;
  341.     Count,Loop : integer;
  342.  
  343. begin
  344.    if G = nil
  345.       then writeln('The Graph does not exist!')
  346.       else begin
  347.               Count := 0;
  348.               Temp := G;
  349.               write('    ');
  350.               while Temp <> nil do
  351.                  begin
  352.                     write(Temp^.Name,' ');
  353.                     Temp := Temp^.Next;
  354.                     inc(Count)
  355.                  end;
  356.               writeln;
  357.               write('  ┌─');
  358.               for Loop := 1 to Count do
  359.                  write('──');
  360.               writeln;
  361.               Temp := G;
  362.               while Temp <> nil do
  363.                  begin
  364.                     Temp2 := G;
  365.                     write(Temp^.Name,' │');
  366.                     while Temp2 <> nil do
  367.                        begin
  368.                           if adjacent( Temp,Temp2 )
  369.                              then write(' 1')
  370.                              else write(' 0');
  371.                           Temp2 := Temp2^.Next;
  372.                        end;
  373.                     Temp := Temp^.Next;
  374.                     writeln
  375.                  end
  376.            end
  377. end;
  378.  
  379.  
  380.  
  381. (***************************************************************************)
  382. (*   Name: PrintArc                                                        *)
  383. (*                                                                         *)
  384. (*   Purpose: Prints the name and weight of the arc between V1 and V2      *)
  385. (*   Input: V1,V2 - Vertices of the arc to be printed                      *)
  386. (*   Output: Name and weight of the arc                                    *)
  387. (***************************************************************************)
  388.  
  389. Procedure PrintArc( V1,V2 : Vertex );
  390.  
  391. begin
  392.    if Adjacent( V1,V2 )
  393.       then writeln( V1^.Name,' ',V2^.Name,' ',ArcWeight( V1,V2 ))
  394.       else writeln('PrintArc Error --- Arc ',V1^.Name,',',V2^.Name,' does not exist ---');
  395. end;
  396.  
  397. end.
  398.