Benutzer: gast • Besitzer: rarom • Zuletzt geändert am: 2010/11/04 10:51:51

program b7auf2RR;
uses crt;

type  pkanten  = ^kanten;
      pgraphen = ^graphen;

      graphen = record
        knoten : integer;
        next   : pgraphen;
        kanten : pkanten;
      end;

      kanten = record
        knoten : pgraphen;
        next   : pkanten;
      end;

var  graph : pgraphen;
     n : integer;



function Graphenanlegen (k: integer):pgraphen;    {Aufbau von hinten}
var i: integer;
    p, anfang: pgraphen;
begin
 anfang:=nil;
 for i:= k downto 1 do
   begin
    new (p);
    p^.knoten:=i;
    p^.next:= anfang;
    anfang:=p;
   end;
 Graphenanlegen:=anfang;
end;


function ZeigeraufKnoten (k:integer; g:pgraphen):pgraphen; {Liefert Zeiger auf Knoten k im Graph g}
begin
  if g = nil then
     ZeigeraufKnoten:=nil
  else
     begin
       while g^.knoten <> k do
         g:=g^.next;
       ZeigeraufKnoten:=g
     end
end;


procedure Kanteneinfuegen (g:pgraphen); {Kanten einlesen und einfuegen}
var a,b:integer;

  function Keinfuegen (g:pgraphen; a,b:integer): pgraphen;
  var k, kante:pkanten;
      p,q:pgraphen;
  begin
    p:=ZeigeraufKnoten(a,g); {Knoten a finden}
    q:=ZeigeraufKnoten(b,g); {Knoten b finden}
    new(kante);              {neue Kante anlegen}
    kante^.knoten:=q;        {Folgeknoten zuweisen}
    if p^.kanten=nil then    {noch keine Kante da?}
         p^.kanten:=kante    {dann Kante direkt einfgen}
    else                     {sonst bis zur letzten Kante weiterhangeln}
      begin
        k:=p^.kanten;
        while k^.next <> nil do
          k:=k^.next;
        k^.next:=kante;      {und anh„ngen}
      end;
    Keinfuegen:= g;
  end;

begin
 writeln ('Eingabe der Kanten a b (Ende mit 0 0) ');
   repeat
     readln (a,b);
      if (a<>0) and (b<> 0) then
        Keinfuegen (g,a,b);
   until a = 0;

end;    {Kanteneinfuegen}



procedure Graphausgabe (g: pgraphen);
var k:pkanten;
begin
 if g=nil then writeln('Graph ist leer') else
   begin
     repeat
       writeln('Knoten: ',g^.knoten);
       k:=g^.kanten;
       while k<>nil do
         begin
          write  ('Kante: ', g^.knoten);
          writeln (k^.knoten^.knoten);
          k:=k^.next;
         end;

       g:=g^.next;
     until g=nil;
   end;
end;   {Graphausgabe}



procedure Kantenausgabe (k:pkanten);
begin
  while k <> nil do
    begin
      writeln (k^.knoten^.knoten);
      k:=k^.next;
    end;
end;   {Kantenausgabe}



procedure Knotenloeschen (k:integer; var g: pgraphen); {call by reference!
                                        sonst kann 1. Knoten nicht gel”scht werden}
var h, hilf:pgraphen;
    kante, loeschkante: pkanten;

  procedure Kantenloeschen (kn:pgraphen);   {loescht alle Kanten des Knoten kn}
  var pkante, loeschkante:pkanten;
  begin
    while kn^.kanten <> nil do
      begin
        pkante:=kn^.kanten;
        if pkante^.next = nil then
          begin
            kn^.kanten := nil;
            dispose (pkante)
          end
        else
          begin
            while pkante^.next^.next <> nil do
              pkante:=pkante^.next;
            loeschkante:= pkante^.next;
            pkante^.next:=nil;
            dispose (loeschkante)
          end;
       end;
   end;   {Kantenloeschen}

begin
   h:=g;   {nach Kanten die auf k zeigen suchen und l”schen}
   while h <> nil do {fr alle Knoten tue}
     begin
       if h^.kanten <> nil then
         begin
           if h^.kanten^.knoten^.knoten = k then   {erste Kante zu l”schen?}
             begin
               loeschkante:=h^.kanten;
               h^.kanten:=h^.kanten^.next;
               dispose (loeschkante);
             end
           else
           begin                                   {gehe alle anderen Kanten durch}
              kante:=h^.kanten;
              while kante^.next <> nil do
              begin
                if kante^.next^.knoten^.knoten = k then
                  begin
                   loeschkante:=kante^.next;
                   kante^.next:=kante^.next^.next;
                   dispose (loeschkante);
                  end
                else
                  kante:=kante^.next ;

              end;
           end;
         end;
       h:=h^.next
     end;
   hilf:=Zeigeraufknoten(k, g);    {Knoten l”schen}
   Kantenloeschen (hilf);
   if g^.knoten=k then
     begin
       hilf:=g;
       g:=g^.next;
       dispose (hilf)
     end
   else
     begin
       h:=g;
       while h^.next^.knoten <> k do  {Vorg„nger des zu l”schenden Knoten suchen}
         h:=h^.next;
       hilf:=h^.next;  {auf zu l”schenden Knoten zeigen}
       h^.next:=h^.next^.next; {šberspringen}
       dispose (hilf)
     end;
end;    {Ende Knotenloeschen}



function Abstand (k:integer; g:pgraphen):pkanten;
var KListe, KZeiger, KZeiger2,Kante, a, pa, paa: pkanten;

  function Abgleich (Einerknoten:pgraphen;Liste:pkanten):pkanten; {Streicht Einerknoten aus Liste}
  var hilf, loesch:pkanten;
  begin
    while (Liste <> nil) and (Liste^.knoten=Einerknoten) do {Vergleich des ersten Eintrags}
        begin
          Liste:=Liste^.next;
          dispose(hilf);
          hilf:=Liste
        end   ;
    hilf:=Liste;
    while (hilf<>nil) and (hilf^.next <> nil) do
          if hilf^.next^.knoten=Einerknoten then
            begin
              loesch:=hilf^.next;
              hilf^.next:=hilf^.next^.next;
              dispose (loesch)
            end
          else
            begin
            hilf:=hilf^.next;
            end;
    Abgleich:=Liste;
  end;

begin
  KListe:=nil;  {alle Knoten mit Entfernung 2 in Liste aufnehmen}
  KZeiger:=ZeigeraufKnoten(k,g)^.kanten;
  while KZeiger<>nil do   {fr alle Kanten tue}
    begin
      KZeiger2:= KZeiger^.knoten^.kanten;  {zeigt auf Kanten des benachbarten Knoten}
      while KZeiger2<> nil do  {Durchlaufen der Kanten des benachbarten Knoten}
        begin
          new(Kante);
          Kante^.knoten:=KZeiger2^.knoten;
          Kante^.next:=KListe; {vorne einh„ngen der neunen Kante}
          KListe:=Kante;
          KZeiger2:=KZeiger2^.next
        end;
      KZeiger:=KZeiger^.next
    end ;
                          {alle Knoten mit Entfernung <2 entfernen}
  KListe:=Abgleich(Zeigeraufknoten(k,g),Kliste); {Schlinge entfernen}
  while KZeiger<>nil do {fuer alle Kanten tue}
    begin
      KListe:=Abgleich(KZeiger^.Knoten, KListe); {Nachbarknoten, Liste}
      KZeiger:=KZeiger^.next;
    end;
  Abstand:=KListe;
end;

{*************Hauptprogramm*******************}
begin
  writeln('Anzahl der Knoten? ');
  readln(n);
  graph:=Graphenanlegen (n);
  Kanteneinfuegen (graph);
  writeln ('Graphausgabe: ');
  readln;
  Graphausgabe (graph);
  readln;
  writeln('Knoten l”schen: ');
  readln(n);
  Knotenloeschen (n,graph);
  Graphausgabe (graph);
  writeln ('Abstand 2 von welchem Knoten?');
  readln (n);
  writeln('Folgende Knoten sind im Abstand 2: ');
  Kantenausgabe (Abstand(n,graph));
  readln;

end.