• Nie Znaleziono Wyników

Wykład 7 - Dynamiczne struktury danych -nieuporządkowane(część I)

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 7 - Dynamiczne struktury danych -nieuporządkowane(część I)"

Copied!
1
0
0

Pełen tekst

(1)

Wykład 7 - Dynamiczne struktury danych -nieuporządkowane(część I) 1. Pojęcie rekurencyjnych typów danych

2. Klasyfikacja struktur danych

3. Podstawowe nieuporządkowane rodzaje dynamicznych struktur danych 4. Stos

5. Kolejka

6. Lista jednokierunkowa 7. Lista dwukierunkowa

1. Pojęcie rekurencyjnych typów danych

Przykład (Wirth N. “Algorytmy + Struktury Danych = Programy”, WNT 1989) a) deklaracja modelu drzewa dziedziczenia:

type osoba = record

if znany then (imię : alfa;

ojciec, matka: osoba)

b) opis reprezentacji zmiennej rodowód typu osoba: end;

jeśli znany = False, to istnieje tylko pole znacznikowe znany równe False (F) jeśli znany = True, to istnieją jeszcze trzy pola (imię, ojciec, matka)

c) przypadek danych: rodowód = (T, Jan, (T, Marek, (T, Adam, (F), (F)), (F)), (T, Maria, (F), (T, Ewa, (F), (F))))

T

Maria

T Ewa T

Marek

T

Adam T

Jan

F F F

F F F

F

wartość False (F) pola znacznikowego określa

skończoność struktury danych, co wynika z braku informacji na pewnym poziomie drzewa genealogicznego

(2)

2. Klasyfikacja struktur danych Struktury danych można podzielić na:

1) typy o stałych rozmiarach - realizowane jako tablice lub rekordy z bezpośrednim dostępem do każdego elementu tych struktur za pomocą operatorów indeksowania “[ ]” lub wyboru: “^.” oraz “.”

2) typy z możliwością zmiany rozmiarów, - rekurencyjne typy danych realizowane jako dynamiczne struktury danych z pośrednim dostępem do ich elementów, przez:

3) użycie rekordów,

4) użycie wskaźników do deklaracji składowych tych rekordów, 5) dynamiczny przydział pamięci dla tych składowych,

6) algorytm dostępu do poszczególnych elementów tego rekordu określa programista dzięki jawnemu użyciu wskaźników.

· Dynamiczne przydzielanie pamięci zmiennej p^.

P

P^

· Wskaźnikowy model rekurencyjnych typów danych:

Przykład Wskaźnikowy model rodowodu a) deklaracja typu

POsoba = ^Osoba;

Osoba = record

Imie : string[10];

Ojciec, Matka : POsoba;

end;

b) wskaźnikowa struktura rodowodu

Jan Marek

Adam Ewa

Maria

nil nil nil

nil

nil nil

Poczatek

(3)

3. Abstrakcyjne typy danych

3.1.Główne cechy typów danych stosowanych w programach:

3.1.1. muszą być dopasowane do rozwiązywanego problemu 3.1.2. muszą zawierać dwa rodzaje informacji:

· zbiór własności

· zbiór działań.

Np. typ integer

własności: reprezentuje liczby całkowite o wartościach od -32768 do +32767 zakodowanych w kodzie dwójkowym na dwóch bajtach

działania: zmiana znaku, dodawanie, mnożenie, dzielenie, modulo...

3.2. Trzy etapy procesu definiowania typów przez programistę [wg Stephen Prata - Szkoła programowania, Język C]:

1) Przygotowanie opisu ADT (abstrakcyjnego typu danych).

“Przygotowania abstrakcyjnego opisu własności typu i operacji, jakie można na nim wykonać. Opis ten nie powinien być związany z żadną konkretną implementacją i językiem programowania. Taka formalna charakterystyka nosi nazwę abstrakcyjnego typu danych ADT.

2) Opracowanie interfejsu programistycznego realizującego ADT -

wskazanie sposobu przechowywania danych i opisanie zbioru funkcji wykonujących potrzebne operacje. W języku C etap ten może polegać na utworzeniu definicji struktury i prototypów funkcji przetwarzających. Funkcje te pełnią dla nowego typu tę samą rolę, co operatory w przypadku podstawowych typów języka C. Utworzony w ten sposób interfejs będzie stosowany przez osoby, chcące skorzystać z nowego typu danych

3) Pisanie kodu implementującego interfejs

Ten krok jest kluczowy, ale należy zauważyć, że programista korzystający z interfejsu nie musi orientować się w szczegółach implementacji”

Wniosek: Utworzony typ danych, definiowany przez programistę stanowi pewien kompletny element języka, który może być używany wielokrotnie w programach. Jedyny właściwy sposób wykorzystania nowego typu odbywa się za pośrednictwem funkcji z interfejsu typu. Nie należy bezpośrednio odwoływać się do zmiennych reprezentujących daną zdefiniowanego typu.

(4)

4. Podstawowe nieuporządkowane dynamiczne struktury danych

Decyzja o zastosowaniu rekurencyjnych struktur danych jest podejmowana przy projektowaniu interfejsu nowego typu

Algorytm dostępu do poszczególnych elementów tej struktury określa programista dzięki jawnemu użyciu wskaźników.

Algorytm dostępu jest podstawą do klasyfikacji dynamicznych struktur danych.

4.1. Stos

Etap 1 - Opis ADT

Nazwa typu - Stos elementów

Własności typu: Potrafi przechować ciąg elementów Dostępne działania:

Inicjalizacja stosu

Określenie, czy stos jest pusty Dodanie elementu do stosu,

Wyszukanie elementu na szczycie stosu Usuwanie ze stosu,

Przejście przez stos i przetwarzanie każdego elementu

Wyszukanie elementu ze szczytu stosu i przetwarzanie tego elementu Usunięcie stosu

Etap 2 - Budowa interfejsu

procedure Inicjalizacja( var Poczatek :PElement);

{ działanie: inicjuje stos

warunki wstępne: Poczatek wskazuje na pierwszy element warunki końcowe: stos zostaje zainicjowany jako pusty}

function Pusty(Poczatek: PElement) : Boolean;

{ działanie: określa, czy stos jest pusty

warunki wstępne: Poczatek jest zainicjowanym stosem,

warunki końcowe: funkcja zwraca True, jeśli stos pusty, w przeciwnym przypadku False }

function Szukaj(Poczatek: PElement) : Boolean;

{ działanie: szuka elementu ze szczytu stosu

warunki początkowe: Poczatek wskazuje na zainicjowany stos,

warunki końcowe: funkcja zwraca True, gdy znaleziono element na szczycie stosu, natomiast zwraca False, jeśli stos jest pusty }

(5)

function Wstaw(var Poczatek: PElement; Pozycja: Osoba): Boolean;

{działanie: dodaje element na początek ciągu, zwany szczytem stosu

warunki początkowe: Pozycja jest daną do wstawienia na szczyt zainicjowanego stosu

warunki końcowe: jeśli to możliwe, funkcja dodaje daną Pozycja na szczyt stosu i zwraca wartosć True, w przeciwnym wypadku False }

function Usun(var Poczatek: PElement): Boolean;

{działanie: usuwa element na początku ciągu wstawionego do stosu warunki początkowe: Poczatek jest zainicjowanym stosem

warunki końcowe: jeśli jest to możliwe, funkcja usuwa element na szczycie stosu i zwraca True, w przeciwnym przypadku False }

procedure Usun_pamiec(var Poczatek: PElement);

{ działanie: usuwa elementy ze stosu i inicjuje stos jako pusty warunki początkowe: Poczatek jest zainicjowanym stosem warunki końcowe: liczba elementów na stosie jest równa 0*/

function Dla_kazdego(Poczatek: PElement, funkcja: zrob): Boolean;

{działanie: wykonuje funkcje na każdym wstawionym elemencie do stosu

warunki początkowe: Poczatek jest zainicjowanym stosem, zrob jest typem funkcji, która pobiera element stosu i nie zwraca wartości

warunki końcowe: jeśli jest to możliwe, funkcja typu zrób jest wykonywana tylko raz dla każdego elementu wstawionego do stosu i funkcja zwraca True, w przeciwnym przypadku False }

function Dla_jednego(Poczatek: PElement; funkcja: zrob): Boolean;

{ działanie: wykonuje funkcja na elemencie ze szczytu stosu

warunki początkowe: Poczatek jest zainicjowanym stosem, zrob jest typem funkcji, która pobiera element ze stosu i nie zwraca wartości

warunki końcowe: funkcja typu zrób jest wykonywana tylko raz dla elementu ze stosu Poczatek , jeśli istnieje i funkcja zwraca True, w przeciwnym przypadku False }

(6)

Etap 3. Implementacja stosu -

Osoba = record

Nazwisko: string[10];

end;

PElement = ^Element;

Element = record

Dane : Osoba;

Nastepny : PElement;

end;

· wstawianie elementów zawsze na początek struktury

Początek „A” „B” nil

Nowy „Z” „A”

Początek

„B” nil

Nowy „Z” nil

function Wstaw(var Poczatek: PElement; Pozycja: Osoba):

Boolean;

var Nowy: PElement;

begin

Nowy:= Nowy_element(Pozycja);

Wstaw:= Nowy<> nil;

if Nowy = nil then Exit; {nie można wstawić, za mało miejsca w pamięci}

Nowy^.Nastepny := Poczatek;

Poczatek := Nowy;

end;

(7)

· usuwanie elementów zawsze na początku struktury

Początek „Z” „A” „B” nil

Początek „Z” „A” „B” nil

Pom

Pom

function Usun(var Poczatek: PElement): Boolean;

var Pom:Pelement;

begin

Usun:= Poczatek <> nil;

if Poczatek = nil then Exit;

Pom := Poczatek; {zapamiętanie pierwszego elementu do usunięcia}

Poczatek := Poczatek^.Nastepny; {odłączenie pierwszego elementu od listy}

Dispose(Pom); {usunięcie pierwszego elementu z pamięci}

end;

{typ proceduralny do obsługi elementu struktury}

type zrob = procedure (Ktory: Osoba);

function Dla_kazdego(Poczatek: PElement, funkcja: zrob): Boolean;

begin

Dla_kazdego:= Poczatel <> nil;

while Poczatek <> nil do begin

funkcja(Poczatek^.Dane);

Poczatek:= Poczatek^.Nastepny;

end;

end;

function Dla_jednego(Poczatek: PElement; funkcja: zrob): Boolean;

begin

Dla_jednego:= Poczatek <> nil;

if Poczatek <> nil then funkcja(Poczatek^.Dane);

end;

(8)

4.2. Kolejka

Etap 1 - Opis ADT

Nazwa typu - Kolejka elementów

Własności typu: Potrafi przechować ciąg elementów Dostępne działania: Inicjalizacja kolejki

Określenie, czy kolejka jest pusta Dodanie elementu do kolejki,

Szukanie elementu na szczycie kolejki, Usuwanie z kolejki,

Przejście przez kolejkę i przetwarzanie każdego elementu

Wyszukanie elementu ze szczytu kolejki i przetwarzanie tego elementu Usunięcie kolejki

Etap 2 - Budowa interfejsu

procedure Inicjalizacja( var Poczatek, Koniec : PElement);

{ działanie: inicjuje kolejkę

warunki wstępne: Poczatek i Koniec wskazują na pustą kolejkę warunki końcowe: kolejka zostaje zainicjowana jako pusta}

function Pusty(Poczatek: PElement) : Boolean;

{ działanie: określa, czy kolejka jest pusta

warunki wstępne: Poczatek jest zainicjowaną kolejką,

warunki końcowe: funkcja zwraca True, jeśli kolejka pusta, w przeciwnym przypadku False }

function Szukaj(Poczatek: PElement) : Boolean;

{ działanie: szuka elementu na szczycie kolejki

warunki początkowe: Poczatek wskazuje na zainicjowaną kolejkę,

warunki końcowe: funkcja zwraca True, gdy znaleziono element na szczycie kolejki, natomiast zwraca False, jeśli kolejka jest pusta }

function Wstaw(var Poczatek,Koniec:PElement;

Pozycja:Osoba):Boolean;

{ działanie: dodaje element na koniec ciągu, zwany końcem kolejki

warunki początkowe: Pozycja jest daną do wstawienia na koniec zainicjowanej kolejki wskazanym przez Koniec

warunki końcowe: jeśli jest to możliwe, funkcja dodaje daną Pozycja na koniec kolejki i zwraca True, w przeciwnym przypadku False }

(9)

function Usun(var Poczatek, Koniec: PElement): Boolean;

{ działanie: usuwa element na początku ciągu wstawionego do kolejki warunki początkowe: Poczatek jest zainicjowaną kolejką

warunki końcowe: jeśli jest to możliwe, funkcja usuwa element na szczycie kolejki i zwraca True, w przeciwnym przypadku False.

Koniec jest równy Poczatek, gdy kolejka jest pusta } procedure Usun_pamiec(var Poczatek, Koniec: PElement);

{ działanie: usuwa elementy z kolejki i inicjuje kolejkę jako pustą warunki początkowe: Poczatek jest zainicjowaną kolejką

warunki końcowe: liczba elementów na stosie jest równa 0, Poczatek jest pustą kolejką i jest równy Koniec }

function Dla_kazdego(Poczatek: PElement, funkcja: zrob): Boolean;

{ tak jak dla stosu}

function Dla_jednego(Poczatek: PElement; funkcja: zrob): Boolean;

{ tak jak dla stosu}

Etap 3. Implementacja kolejki - definicja elementów kolejki jak dla stosu

· wstawianie elementów zawsze na końcu struktury

Początek „A” „B” nil

Nowy „Z”

Początek „A” „B”

Nowy „Z”

nil

Koniec

Koniec

nil

function Wstaw(var Poczatek,Koniec:PElement; Pozycja:

Osoba): Boolean;

var Nowy: PElement;

begin

Nowy:= Nowy_element(Pozycja);

Wstaw:= Nowy <> nil;

if Nowy = nil then Exit; {nie można wstawić, za mało miejsca w pamięci}

if Poczatek := nil then Poczatek := Nowy

else Koniec^.Nastepny := Nowy;

Koniec := Nowy;

end;

· usuwanie elementów zawsze na początku struktury (jak w przypadku stosu).

W przypadku, gdy po usunięciu stos staje się pusty - Koniec jest równy Poczatek:

(10)

if Poczatek = nil then Koniec = nil;

(11)

· 4.3. Lista nieuporządkowana Etap 1 - Opis ADT

Nazwa typu - Lista elementów

Własności typu: Potrafi przechować ciąg elementów Dostępne działania: Inicjalizacja listy

Określenie, czy lista jest pusta Dodanie elementu do listy,

Wyszukanie elementu na wskazanym miejscu na liście, Usuwanie z listy,

Przejście przez listę i przetwarzanie każdego elementu Wyszukanie elementu z listy i przetwarzanie tego elementu Usunięcie listy

Etap 2 - Budowa interfejsu

procedure Inicjalizacja( var Poczatek : PElement);

{ działanie: inicjuje listę

warunki wstępne: Poczatek wskazują na pustą listę warunki końcowe: lista zostaje zainicjowana jako pusta}

function Pusty(Poczatek: PElement) : Boolean;

{ działanie: określa, czy lista jest pusta

warunki wstępne: Poczatek jest zainicjowaną listą,

warunki końcowe: funkcja zwraca True, jeśli lista pusta, w przeciwnym przypadku False }

function Szukaj(Po czatek:

PElement;

Miejsce:

word; var Gdzie:

PElement) : Boolean;

{ działanie: szuka elementu na liście

warunki początkowe: Poczatek wskazuje na zainicjowaną listę, warunki końcowe: funkcja zwraca wskazanie Gdzie na element wskazujący na element o numerze Miejsce, gdy znaleziono go na liście lub wskazanie puste, gdy element jest na początku listy lub Gdzie wskazuje na koniec listy i zwraca True, w przeciwnym wypadku False }

function Wstaw(v

(12)

ar

Poczatek :PEleme nt;Pozycj a:Osoba;

Gdzie:PE lement):

Boolean;

{ działanie: dodaje element w dowolne miejsce ciągu umieszczonego na liście warunki początkowe: Pozycja jest daną do wstawienia na miejscu pośrednio wskazywanym przez Gdzie zainicjowanej listy Poczatek.

warunki końcowe: funkcja dodaje daną Pozycja na miejscu określonym przez funkcję Szukaj lub do pustej listy i zwraca True, w przeciwnym wypadku zwraca False}

(13)

function Usun(var Poczatek: PElement; Gdzie: PElement):

Boolean;

{ działanie: usuwa element na dowolnym miejscu w ciągu wstawionym do listy

warunki początkowe: Poczatek jest zainicjowaną listą, Gdzie jest pośrednim wskazaniem na element usuwany określony przez funkcję Szukaj

warunki końcowe: funkcja usuwa z listy element określony przez funkcję Szukaj, lecz pomija przypadek wskazania przez Gdzie ostatniego elementu listy i zwraca True, w przeciwnym wypadku False}

procedure Usun_pamiec(var Poczatek, Koniec: PElement);

{ tak jak dla stosu}

function Dla_kazdego(Poczatek: PElement, funkcja: zrob): Boolean;

{ tak jak dla stosu}

functio n

Dla_jed nego(Po czatek, Gdzie:

PEleme nt;

funkcja:

zrob):

Boolean

;

{ działanie: szuka elementu na liście i wykonuje na nim czynność

warunki początkowe: Poczatek wskazuje na zainicjowaną listę, warunki końcowe: funkcja wykonuje czynność funkcja na elemencie wskazanym pośrednio przez Gdzie określonym przez funkcję Szukaj z wyłączeniem przypadku, gdy Gdzie wskazuje na ostatni element listy i zwraca True, w przeciwnym wypadku False }

(14)
(15)

Etap 3 - implementacja jako lista jednokierunkowa- element listy jak dla stosu

· szukanie w dowolnym miejscu

Początek „A” „D” nil

Nowy „Z”

Początek „A” „B”

Nowy „Z”

nil

Miejsce =3

Gdzie

„B”

„D” nil Nast Gdzie

function Szukaj(Pocz atek:PEleme nt; Miejsce:

word; var Gdzie:PEle ment):

Boolean;

var Numer : integer; Nast : PElement;

begin

Gdzie:= nil; Szukaj:= False;

if Poczatek = nil then Exit; {nie wstawiono, za mało miejsca w pamięci}

Numer := 1; Nast := Poczatek;

while (Nast^.Nastepny <> nil) and (Miejsce <> Numer) do begin

Gdzie := Nast; Nast := Nast^.Nastepny; inc(Numer);

end;

Szukaj:= (Miejsce = Numer) or (Miejsce = Numer+1);

if Miejsce = Numer + 1 then Gdzie:= Nast;

end;

· wstawianie elementu na dowolne miejsce na liście lub jako pierwszy na pustej

function Wstaw(v ar

Poczatek :PEleme nt;Pozycj a:Osoba,

(16)

Gdzie:PE lement):

Boolean;

var Nowy: PElement;

begin

Nowy:= Nowy_element(Pozycja);

Wstaw:= Nowy <> nil;

if Nowy = nil then Exit;

if Gdzie = nil then begin {wstaw na początku listy lub zakładanie listy}

Nowy^. Nastepny := Poczatek; Poczatek := Nowy;

end

else begin {wstaw wewnątrz listy lub na jej końcu}

Nowy^.Nastepny := Gdzie^.Nastepny; Gdzie^.Nastepny := Nowy;

end;

end;

· usuwanie elementu w dowolnym miejscu niepustej listy

Poczatek „B” „Z”

Miejsce = 2

Gdzie

„D” nil

Poczatek „B” „Z” „D” nil

Gdzie

Poczatek „B” „Z” „D” nil

function Usun(var Poczatek: PElement; Gdzie: PElement):

Boolean;

var Pom : PElement begin

Usun:= False;

if Gdzie= nil then begin

Pom:= Poczatek; Poczatek:=

Poczatek^.Nastepny;

end else begin

if Gdzie^.Nastepny = nil then Exit;

Pom:= Gdzie^.Nastepny; Gdzie^.Nastepny:=

Pom^.Nastepny;

end;

Dispose (Pom);

(17)

Usun:= True;

end;

functio n

Dla_jed nego(P oczate k, Gdzie:

PElem ent;

funkcja : zrob):

Boolea n;

begin Dla_jednego:= False;

if Gdzie= nil then Gdzie:= Poczatek else

if Gdzie^.Nastepny <> nil then Gdzie:= Gdzie^.Nastepny else Exit;

funkcja(Gdzie^.Dane);

Dla_jednego:=True;

end;

(18)

· Etap 3. Implementacja w postaci listy dwukierunkowej nieuporządkowanej

Realizacja typu lista nieuporządkowana w postaci listy dwukierunkowej: nie zmieniły się algorytmy: Usun_Pamiec, Dla_każdego, Dla_jednego, Inicjalizacja, Pusty.

Osoba = record

Nazwisko: string[10];

end;

PElementD = ^OsobaD;

OsobaD = record

Poprzedni : PElementD;

Dane : Osoba;

Nastepny : PElementD;

end;

· wyszukiwanie w dowolnym miejscu listy

nil nil

„D”

nil Poczatek „B” nil

Nowy

Miejsce = 2

„Z”

nil „D” nil

Poczatek „B”

Gdzie

Nowy „Z”

function Szukaj(P oczatek:

PElement D;

Miejsce:w ord; var Gdzie:

PElement D):

Boolean;

var Numer : integer; {algorytm ten sam, w liście można przechodzić w obu kierunkach}

begin

Gdzie:= Poczatek; Szukaj:= False;

(19)

if Poczatek= nil then Exit;

Numer:= 1;

while (Gdzie^.Nastepny <> nil) and (Miejsce <> Numer) do begin

Gdzie := Gdzie^.Nastepny; inc(Numer);

end;

Szukaj:=(Miejsce = Numer) or (Miejsce=Numer+1);

{Gdzie wskazuje na element wskazujący na Miejsce}

if (Miejsce = Numer) then Gdzie:= Gdzie^.Poprzedni;

end;

(20)

· wstawianie w dowolnym miejscu listy niepustej oraz jako pierwszy na pustej

function Wstaw(var

Poczatek:PElementD;Pozycja:O soba;Gdzie: PElementD):

Boolean;

var Nowy: PElementD;

begin

Nowy:= Nowy_elementD(Pozycja);

Wstaw:= Nowy <> nil;

if Nowy = nil then Exit; {nie wstawiono, za mało miejsca w pamięci}

if Gdzie= nil then {wstaw na początku listy}

begin

Nowy^.Nastepny := Poczatek; {podłącz z prawej na początku}

if Poczatek <> nil then

Poczatek^.Poprzedni := Nowy; {podłącz z prawej na początku}

Poczatek := Nowy; {podłącz z lewej na początku}

end else

begin {wstaw wewnątrz listy lub na końcu}

Nowy ^. Nastepny:= Gdzie^.Nastepny; {podłącz z prawej w środku lub na końcu}

if Gdzie^.Nastepny <> nil then

Gdzie ^.Nastepny ^.Poprzedni := Nowy; {podłącz z prawej w środku}

Gdzie^.Nastepny := Nowy; {podłącz z lewej w środku lub na końcu}

end;

Nowy^.Poprzedni:= Gdzie; {podłącz z lewej w obu przypadkach}

end;

(21)

· usuwanie elementu w dowolnym miejscu listy niepustej

nil „Z”

Poczatek

„B”

Miejsce = 2

Gdzie (Usun)

„D” nil

nil „Z”

Poczatek

„B” „D” nil

nil „Z”

Poczatek

„B” „D” nil

Gdzie (Szukaj)

Gdzie (po Usun)

function Usun(var Poczatek: PElement; Gdzie: PElement): Boolean;

begin

Usun:= False;

if Gdzie = nil then Gdzie := Poczatek {korekcja wskaźnika Gdzie}

else

if Gdzie^.Nastepny <> nil then Gdzie := Gdzie^.Nastepny

else Exit; {wyjście, gdy wskazano miejsce za ostatnim elementem}

if Gdzie^.Poprzedni <> nil then {odłącz na lewo}

Gdzie^.Poprzedni^.Nastepny := Gdzie^.Nastepny; {odłącz w środku na lewo}

else Poczatek := Gdzie^.Nastepny; {odłącz na początku na lewo}

if Gdzie^.Nastepny <> nil then {odłącz w środku na prawo}

Gdzie^.Nastepny^.Poprzedni:= Gdzie^.Poprzedni;

Dispose(Gdzie);

Usun:= True;

end;

(22)

Przykład zastosowania interfejsu listy dwukierukowej nieuporządkowanej

program Lista_nieuporzadkowana_dwukierunkowa;

uses Crt, Rozne, Modul, MListDLN;

const Tab_menu : Lancuchy =

('1 : Zakladanie listy nieuporzadkowanej dwukierunkowej', '2 : Usuwanie z listy nieporzadkowanej dwukierunkowej',+

'3 : Wydruk listy nieuporzadkowanej dwukierunkowej', '4 : Usun liste nieupoprzadkowana dwukierunkowa', 'K/k - Koniec programu','','','','','','');

procedure Podaj_miejsce(var Miejsce:word); {...}

procedure Wstaw_do_listy(var Poczatek: PElementD);

var Gdzie : PElementD; Dana : Osoba; Miejsce: word; Z: char;

begin

Podaj_dane(Dana); Podaj_miejsce(Miejsce);

if Szukaj(Poczatek,Miejsce, Gdzie) or Pusty(Poczatek) then begin

Wstaw(Poczatek,Dana,Gdzie);

Dla_jednego(Poczatek,Gdzie,Wydruk_danych); Pauza(Z, False);

end;

end;

procedure Usun_z_listy(var Poczatek: PElementD);

var Gdzie : PElementD; Miejsce: word; Z: char;

begin

Podaj_miejsce(Miejsce);

if Szukaj(Poczatek,Miejsce,Gdzie) then Writeln(Usun(Poczatek, Gdzie));

Pauza(Z,False);

end;

var Wybor, Z : char; Poczatek_DLN : PElementD;

begin

ClrScr; Randomize;

Inicjalizacja(Poczatek_DLN);

repeat

Menu(Tab_menu, 5, Wybor);

case Wybor of

'1' : Wstaw_do_listy(Poczatek_DLN);

'2' : Usun_z_listy(Poczatek_DLN);

'3' : begin

Writeln(Dla_kazdego(Poczatek_DLN, Wydruk_danych)); Pauza(Z,False);

end;

'4' : Usun_Pamiec(Poczatek_DLN);

end;

until Wybor = 'K';

end.

Cytaty

Powiązane dokumenty

Utwórz zapytanie, które wyświetli nazwisko, imię, wiek pracownika i komentarz (osobom poniżej 40 ma się wyświetlić „junior”, osobom od 40 – „senior”).. Ćwiczenie

pełny wniosek (np. dostrzeżenie aktualności przedstawionego w utworze problemu; zwrócenie uwagi na rolę religii w życiu młodych ludzi; pogląd na znaczenie ojczyzny; pogląd

Gdy połowa populacji ma IQ poniżej 100 (…), problemy, z któ- rymi boryka się rząd, są bardzo zło- żone, zwykli obywatele wykazują za- interesowanie złożonymi kwestiami

{ działanie: usuwa największy element wstawiony do kolejki priorytetowej, warunki początkowe: Kolejka_P jest niepustą kolejką priorytetową. warunki końcowe: usuwa element

{ działanie: podaje największy element o numerze numer z listy symboli Slownik, warunki początkowe: Slownik jest zainicjowaną niepustą listą symboli. warunki końcowe: podaje

{działanie: usuwa elementy ze stosu i inicjuje stos jako pusty warunki początkowe: Poczatek jest zainicjowanym stosem warunki końcowe: liczba elementów na stosie jest równa 0}.

Zatem, jeśli istniałby algorytm wielomianowy do rozwiązywa- nia jakiegokolwiek problemu NP-zupełnego, to każdy problem z klasy NP (w tym również problemy NP-zupełne)

Problem