Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[PASCAL] Lista 2 kierunkowa

Orestesik 03 Sty 2011 19:19 2334 2
  • #1 03 Sty 2011 19:19
    Orestesik
    Poziom 8  

    Witam,
    To jest mój pierwszy post więc proszę o wyrozumiałość, staram się zrozumieć listy 2 kierunkowe ( bo potrzebuje ich do projektu na studiach)
    ale nie o tym mam problem z funkcją szukaj oraz nie mam najmniejszego pomysłu jak zapisać dodane rekordy do pliku oraz je z pliku wczytać

    Code:
    program Lista2k;
    

    {$APPTYPE CONSOLE}
    uses
      SysUtils;
      //Win32Crt;

    type
    {rekord - plik binarny}
      osoba = record
        im, nazw : string[20];
      end;

    {rekord - lista dwukierunkowa}
      wsk = ^dane;
      dane = record
        im, nazw : string[20];
        pop : wsk;
        nast : wsk
      end;

    var
      glowa, szukany : wsk;
      zap : osoba;
      znak : char;
      imie, nazwisko, naz : string;

    {wstawia element do listy na odpowiednie miejsce - tworzy posortowana
     wzgledem nazwiska liste dwukierunkowa}
    procedure WstawSort(imie : string; nazwisko : string);
    var
       nowy:wsk;
       bierz:wsk;
      pop:wsk;
    begin
       new(nowy);
       nowy^.im:=imie;
      nowy^.nazw:=nazwisko;
       if glowa=nil then
       begin
          nowy^.pop:=nil;
          nowy^.nast:=nil;
          glowa:=nowy;
       end
       else
       begin
         bierz:=glowa;
         pop:=glowa;

       while (bierz<>nil) and (bierz^.nazw<=nazwisko) do
       begin
          pop:=bierz;
          bierz:=bierz^.nast
       end;
       if bierz=nil then
       begin
          pop^.nast:=nowy;
          nowy^.pop:=pop;
          nowy^.nast:=nil;
       end
       else if bierz^.pop=nil then
       begin
          nowy^.pop:=nil;
          nowy^.nast:=bierz;
          bierz^.pop:=nowy;
          glowa:=nowy;
       end
       else
       begin
          nowy^.pop:=pop;
          nowy^.nast:=bierz;
          pop^.nast:=nowy;
          bierz^.pop:=nowy;
       end;
      end;
    end;

    {funkcja wyszukuje element o podanym nazwisku
     zwraca wskaznik na znaleziony element}




    function Szukaj(nazwisko : string) : wsk;
    var
       bierz:wsk;
       jest:boolean;
    begin
       jest:=false;
       bierz:=glowa;
       while((bierz<>nil) and (not jest)) do
       begin
          if (bierz^.nazw=nazwisko) then
        jest:=true;
        bierz:=bierz^.nast;
       end;
       if (jest) then
      begin
      szukaj:=bierz;
      end;
    end;

    {procedura drukuje liste dwukierunkowa
     true - od poczatku, false - od konica}
    procedure Drukuj(kierunek : boolean);
    begin
    end;

    {procedura rekurencyjna drukowania listy}
    procedure DrukujRek(wsk : wsk);
    begin
     if wsk <> nil then
     begin
       DrukujRek(wsk^.nast);
       writeln(wsk^.im, ' ', wsk^.nazw);
     end;
    end;

    {usuwanie rekordu z listy o podanym wskazniku}
    procedure Usun(var usuwany : wsk);
    var
    bierz:wsk;
    begin
       if ((usuwany<>nil) AND (glowa<>nil)) then
       begin
          if usuwany^.pop=nil then
          begin
             glowa:=usuwany^.nast;
             if glowa <>nil then
          glowa^.pop:=nil;
             dispose(usuwany);
          end
          else if (usuwany^.nast=nil) then
          begin
             usuwany^.nast:=nil;
             dispose(usuwany);
          end
          else
          begin
             usuwany^.pop^.nast:=usuwany^.nast;
             usuwany^.nast^.pop:=usuwany^.pop;
             dispose(usuwany);
          end;
       end;
    end;

    {wczytuje elementy z pliku binarnego o przekazanej nazwie i wstawia do listy}
    procedure WczytajZPliku(nazwa : string);
    var
      plik : file of osoba;

    begin
    end;

    {zapisuje wszystkie elementy do pliku binarnego o przekazanej nazwie}
    procedure ZapiszDoPliku(nazwa : string);
    var
      plik : file of osoba;
    begin
        Assign(plik, 'test.dat');
        rewrite(plik);
        writeln(zap.im);
        writeln(zap.nazw);
        close(plik);

    end;

    {usuwa liste z pamieci}
    procedure Zeruj;
    var
      temp, biezacy : wsk;

    begin
      biezacy := glowa;
      while biezacy <> nil do
      begin
        temp := biezacy;
        biezacy := biezacy^.nast;
        dispose(temp);
      end;
      glowa := nil;
    end;

    begin
      glowa := nil;
      repeat
        //clrscr;
        writeln('Obsługa listy dwukierunkowej - podstawowe operacje');
        writeln('1 - Wstaw element');
        writeln('2 - Usun element');
        writeln('3 - Drukuj cala liste - od początku');
        writeln('4 - Drukuj cala liste - od końca');
        writeln('5 - Drukuj cala liste - rekurencyjnie');
        writeln('6 - Usun liste');
        writeln('7 - Wczytaj elementy z pliku binarnego');
        writeln('8 - Zapisz elementy do pliku binarnego');
        writeln('k,K - Koniec');
        writeln;
        readln(znak);
        case znak of
          '1' : begin
                  writeln('Podaj imie');
                  readln(imie);
                  writeln('Podaj nazwisko');
                  readln(nazwisko);
                  WstawSort(imie, nazwisko);
                end;
          '2' : begin
                  writeln('Podaj nazwisko do usuniecia');
                  readln(nazwisko);
                  szukany := Szukaj(nazwisko);
                  if szukany = nil then
                    writeln('W liscie nie ma takiego elementu')
                  else
                    Usun(szukany);
                end;
          '3' : begin
                  Drukuj(true);
                  readln;
                end;
          '4' : begin
                  Drukuj(false);
                  readln;
                end;
          '5' : begin
                  DrukujRek(glowa);
                  readln;
                end;
          '6' : begin
                  Zeruj;
                end;
          '7' : begin
                  writeln('Odczytywanie z pliku...');
                  writeln('Podaj nazwe pliku binarnego');
                  readln(naz);
                  WczytajZPliku(naz);
                  readln;
                end;
          '8' : begin
                  writeln('Zapisywanie do pliku...');
                  writeln('Podaj nazwe pliku binarnego');
                  readln(naz);
                  ZapiszDoPliku(naz);
                  readln;
                end;

        end;
      until (znak = 'k') or (znak = 'K');
      Zeruj; {!!! Zawsze nalezy usunac zajeta w programie pamieci}
      //DoneWinCrt;
      readln;
      readln;
    end.


    Problem w szukaniu jest następujący, w obecnej formie (usuwa mi rekord jeden wcześniej zależy czy dodam pop czy nast ) a co do tych operacjach na plikach nie wiem jak wczytać to ani jak to zapisać do tego chorego pliku :/

    Pozdrawiam,
    Orestes

    0 2
  • Pomocny post
    #2 04 Sty 2011 15:05
    arnoldziq
    Moderator Programowanie

    Sama nazwa; listy dwukierunkowej pochodzi od tego, że dowolny element listy, zawiera adres elementu poprzedzającego dany element na liście, a także adres elementu następnego na liście.
    W ten sposób, znając adres dowolnego elementu, możesz prześledzić całą listę, bez potrzeby wiedzy o "położeniu" każdego elementu z osobna; wystarczy znać tylko adres jednego z elementów listy.
    Lista dwukierunkowa, (zgaduję, ze nie ma to być lista dwukierunkowa cykliczna) jest dość prosta jeżeli chodzi o operacje na niej, ponieważ ma ona bardzo wyraźnie "zarysowany" początek i koniec. Początkowym elementem listy będzie element, który nie ma swojego poprzednika. Ostatnim elementem listy, będzie element, który nie ma swojego następcy.
    W obu przypadkach, wystarczy, sprawdzić czy odpowiedni wskaźnik zawiera jakąś informację, czy też jest równy nil.
    W Twoim przypadku, problemem jest to, że próbujesz zapisać do pliku tylko jeden element z listy.
    Dobrym rozwiązaniem, byłoby, (przed zapisem do pliku) "cofnięcie" się do początku listy i zapisywanie kolejnych rekordów (elementów), aż do napotkania ostatniego elementu listy.
    Podobnie sprawa ma się z odczytem z pliku; metodologia jest taka :
    1. Czyścisz pamięć, usuwasz listę, która jest w pamięci.
    2. Czytasz pierwszy rekord z pliku - tworzysz element w pamięci - ponieważ jest to pierwszy (i jak na razie ostatni) element twojej listy, spokojnie możesz ustawić oba wskaźniki (poprz,nast) ustawić na nil.
    3. Sprawdzasz czy to już koniec pliku z którego czytasz - jeżeli tak; odczyt został zakończony - twoim bieżącym elementem jest ostatni przeczytany z pliku element listy.
    4. Odczytujesz kolejny rekord (element) z pliku - tworzysz go w pamięci, ustawiasz mu wskaźnik (nast) na nil, a wskaźnik poprzednika ustawiasz na "bieżący" element listy. Następnie zmieniasz "wskaźnik bieżący" na właśnie utworzony element.
    5. Powrót do punktu 3.
    Proste, prawda ?

    0
  • #3 04 Sty 2011 16:37
    Orestesik
    Poziom 8  

    zarys dałeś jakiś, jutro postaram się coś wykminić i dam znać :)
    Dzięki

    0