• Nie Znaleziono Wyników

9.3. Obroty w węzłach

N/A
N/A
Protected

Academic year: 2021

Share "9.3. Obroty w węzłach"

Copied!
15
0
0

Pełen tekst

(1)

Wykład 9 - struktury dynamiczne uporządkowane (część 2) 9.1. Drzewa (c.d.)

9.2. Definicje

9.3. Obroty w węzłach

9.4. Wstawianie do korzenia drzew binarnych 9.5. Wyważanie drzew binarnych

9.6. Przejście prze drzewo

9.2. Złożoność obliczeniowa drzew i list

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 91

(2)

9.1.1. Definicje drzew Definicja 1:

Drzewa to matematyczna abstrakcja, która umożliwia:

· opisywanie własności algorytmów ( np algorytmy: dziel i zwyciężaj” , kopcowanie)

· opisywanie konkretnych struktur danych, które są realizacjami drzew (np.

drzewa poszukiwań binarnych, drzewa czerwono-czarne, B-drzewa).

Klasyfikacja drzew:

· drzewa binarne i m-drzewa

· drzewa z korzeniem

· drzewa uporządkowane

· drzewa swobodne

w ęzeł

zew nętrzny

w ęzeł

w ew nętrzny 20

10 30

35

40 50

60

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 9

Definicja 2:

Drzewo binarne to węzeł zewnętrzny lub dołączony do pary drzew

binarnych, które nazywa się odpowiednio lewym i prawym poddrzewem tego węzła.

Definicja 3:

M-drzewo to węzeł zewnętrzny lub węzeł wewnętrzny dołączony do uporządkowanego ciągu drzew, które są również m-drzewami.

Definicja 4: Drzewo z korzeniem (lub drzewo nieuporządkowane) to węzeł (nazywany korzeniem) połączony z wielozbiorem drzew z korzeniem.

Taki wielozbiór nazywamy jest lasem nieuporządkowanym.

Drzewa nieuporządkowane są często reprezentowane w programach jako drzewa uporządkowane.

2

(3)

ojciec

Syn(następca) węzeł

brat

liść korzeń

10 20 40

35 50 60

30

Definicja 6: Istnieje jednoznaczne odwzorowanie drzew binarnych na lasy uporządkowane i na odwrót.

20

20 10

19 13

15 16

17

10 19

13 15 16 17

10 19

13 15 16

20

17 20

10

19 13

15

16

17

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 9

Definicja 5: Drzewo uporządkowane to węzeł (nazywany korzeniem) dołączony do ciągu rozłącznych drzew. Taki ciąg nazywany jest lasem. W przeciwieństwie do m-drzew może mieć dowolną liczbę synów ( następców), lecz ustala się ich kolejność (porządek).

3

(4)

Definicja 7: Drzewo swobodne czyli drzewo bez korzenia to graf, który zawiera n-1 krawędzi i nie ma cykli, jest spójny, każde dwa wierzchołki łączy dokładnie jedna ścieżka prosta.

Graf jest parą zbiorów węzłów i krawędzi łączących po dwa różne węzły, przy czym każde dwa węzły łączy co najwyżej jedna krawędź.

Ścieżka prosta to ciąg krawędzi prowadzący od jednego węzła do innego, w którym nie powtarza się żaden węzeł dwukrotnie.

Graf jest spójny, jeśli jego dowolne dwa węzły można połączyć ścieżką prostą.

Ścieżka jest cyklem wtedy, gdy różni się od ścieżki prostej tylko tym, że pierwszy i ostatni węzeł to ten sam węzeł.

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 94

(5)

9.1.2. Obroty w węzłach

· obrót w lewo

A

E

C

E

C A

procedure Obrot_L(var Wezel : POsobaD);

var P : POsobaD;

begin

P := Wezel^.Prawy;

Wezel^.Prawy := P^.Lewy;

P^.Lewy := Wezel;

Wezel := P;

end;

· obrót w prawo

E A

C

A

C

E

procedure Obrot_P(var Wezel : POsobaD);

var P : POsobaD;

begin

P := Wezel^.Lewy;

Wezel^.Lewy := P^.Prawy;

P^.Prawy := Wezel;

Wezel := P;

end;

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 95

(6)

9.1.3. Wstawianie do korzenia drzewa

· Wstaw następujący ciąg: 8, 6, 7, 9, 3, 11, 2, 5, 4, 10, 15, 13 do drzewa binarnego jako liście

8

6 9

3

1

2 4

5 1 8

8

6

8

6 9

1 2

1

2 4

8

6 9

3

5

11 1 2

1

2 4

5

8

6

7 8

6 9

3 11

1

2 4

5 6

8

6 9

3 11

2

1

2 4

5 6

8

6 9

3

1

2 4

5

11 6

6

8

6 9

3

5 10

11

2

1

2 4

5

8 10

6

7 8

6 9

3

5 10

11

2

1

2 4

5

8 10

6 7

7

8

6 9

3

5

4 11

2

1

2 4

5

8

9 6

7

4 9

4 9

15 11 2

7

5 8

4 9

10 10

15 11

13 12

7 7 7

7 7 7

7 7 7

3

3

3 3

3

3

3 3

3

8

6 1 2

7 3

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 96

(7)

· Wstaw następujący ciąg: 8, 6, 7, 9, 3, 11, 2, 5, 4, 10, 15, 13 wstawiając do korzenia drzewa

6

7

8 8

6

6

8

9

3

8

7

6 9

8

9

7

6

3

7

6 8

9

11

2

7

8

5 6

9

11

6 8

8 7

3

7 9

7

3

6 8

9 3

8 6

7

11 9 3

8 6

7

2 3

9 11

6 7

8

2

11

7

6 8 9 3

6 2

11

7

5 8 9 3

8 2

11

5

7

6 9 3

8 2

11

9

7

6 5 3

8 2

11

9

7

6 5

3

8 2

5

9

7

6

11 3

8 5

3 9

7

6 2 11

4

8 5

4 9

7

6 2 11

3

8 5

2 9

7

6 4 11

3

8 4

9 11

7

6 2 5

3

1 1

2

2

1

3

2

3

1

3

1 2

4

2

3

1 4

4

3

2 1

5

4 3

5 1

2

4 5

3

2 1

5

3 6

2 1

4

5

6

4

5

7

3

2 1

4

3

2 1

6

6

7

5

4

7

6

5

4

7 7

6

5

4

5

4

3

2 1

3

2 1

8

3

8 1

2

5

8

8 4

3 3

2 1 2 1

7

6 6

2 1

5 4

8

3 7

6

7 8 8

8

5 6

7 6

5 4

7 6 9

9 4 7

4 9

3

5 3 5

3

2 1 2 1 2

2 1

8

6 7

4

3

1

9

8

5 6

4

3

2 1

Autor: Zofia Kruczkiewicz, p.325 C3 Algorytmy i struktury danych, Wykład 97

(8)

8 4

9 11

7 6 2 5

3

10

8 4

9

11

7 6 2 5

3

10

8 4

9 10

7 6 2 5

3

11

8 4

9 11

7 6 2 10

3 5

8 10

5 15

7 6

11 2

3 4

9

8 10

5 11

7 6

15 2

3 4

9

8 10

5

7 6

11 2

3 4

9 15

13

10

5

7

13 2

3 4

9 15

11

10

5

7

11 2

3 4

9 13

15

10

5

7

11 2

3 4

9 13

15

8

8 6

6

6 8

9 7

5

8

6

4

9

7 8

5

7 9

6 5

8

10

10

4

9

7 10

5 8 6

6 4

3

2 1

3

2 1

3 10 4

2 1 3

2 1

10

9 6

10

9 11

7 8 11 7 8 6 9

5 4

3

5 4

3

7 8

5

2 1 2 1

11

10

6

12

4

3

2 1

11 11

10 12

12 10

9 12 10

7 8 6 9 6

9

7 8

6

8

7 5

5 4

5 4

3

2 1 3

2 1

3 4

2 1

11

(9)

procedure Wstaw_korzen(var Wezel,Nowy : POsobaD);

begin

if Wezel = nil then Wezel := Nowy else

if Wezel^.Dane.Nazwisko > Nowy^.Dane.Nazwisko then begin

Wstaw_korzen(Wezel^.Lewy, Nowy);

Obrot_P(Wezel);

end else

if Wezel^.Dane.Nazwisko < Nowy^.Dane.Nazwisko then begin

Wstaw_korzen(Wezel^.Prawy, Nowy);

Obrot_L(Wezel);

end else begin

Dispose(Nowy); Nowy:= nil;

end;

end;

(10)

9.1.4. Wyważanie drzewa

10

5

7

11

2

3 4

9 13

15

8

10

5

8

11

2

3 4

9 13

15

7 6

10

5

9 11

2

3 4

8 13

15

7 6

10

8

5

11 2

3 4

9 13

15

7 6 6

10

9 2

11 4

5 8

3

13 15

7 6

8

9 2

4 10

5 3

13 15

7 6

11

8

2 10 4 13

5 3

15

7 6

11

2 4

5

3 7

6

4 5

7 2 6

3

4

2

3

2 3

4 4

3 2

3 5

7

2 4 6

10 13

15

11

9

9

11 13

15

9 10

10 11

13

9 15

10 11

15

9 13 4

5

7

2 4 6

8

12 10

9

7 8

5 4

12 11

6

10 11

9 6

7 8

5 4

9 10

12

11

12

10 11

7 8

9 6

7 1

5 8 4

5 1

6

3 2

3 4

2 1

3

2 3

2 1

12

10 11

6 1

9 4

12

1 11

9 10

4

7 8 4 6

7 8

5 3

2

5 3

2

1

9 12

7 8 10 11

5 3 4 6

2

9

5 5

7 9 3

7 9 2

9

5

7 9

7

5 8

9 3

7 2

5 9

7 8

5 3

2

12

10 11

4 6

12

6

10

6

10 12

4 11

11

4

1

8

9

7 9

3

6

2 4

10 11

12

10 11

13 15

9

6

10

12 4

11

(11)

procedure Wywaz_drzewo(var Wezel : POsobaD);

begin

if (Wezel = nil) or (Wezel^.Licznik = 1) then exit;

Podzial(Wezel,Wezel^.Licznik div 2);

Wywaz_drzewo(Wezel^.Lewy);

Wywaz_drzewo(Wezel^.Prawy);

end;

procedure Podzial(var Wezel : POsobaD; Liczba : integer);

var il : integer;

begin

if Wezel^.Lewy = nil then il :=0 else il:= Wezel^.Lewy^.Licznik;

if il > Liczba then begin

Podzial(Wezel^.Lewy, Liczba);

Obrot_P(Wezel);

Oblicz_wezly(Wezel);

end else

if (il < Liczba) then begin

Podzial(Wezel^.Prawy, Liczba - il - 1);

Obrot_L(Wezel);

Oblicz_wezly(Wezel);

end;

end;

function Oblicz_wezly(Wezel: POsobaD) : integer;

begin

if Wezel <> nil then begin

if (Wezel^.Prawy = nil) and (Wezel^.Lewy = nil) then Wezel^.Licznik:=1

else

Wezel^.Licznik:= Oblicz_wezly(Wezel^.Lewy)+

Oblicz_wezly(Wezel^.Prawy)+1;

Oblicz_wezly:= Wezel^.Licznik;

end

else Oblicz_wezly := 0;

end;

(12)

procedure Obrot_LL(var Wezel : POsobaD);

var P : POsobaD; x1, x2, x3 : longint;

begin

x1:= 0; x2:= 0; x3:= 0;

if Wezel^.Lewy <> nil then x1:= Wezel^.Lewy^.Licznik;

if Wezel^.Prawy^.Lewy <> nil then x2:= Wezel^.Prawy^.Lewy^.Licznik;

if Wezel^.Prawy^.Prawy <> nil then x3:= Wezel^.Prawy^.Prawy^.Licznik;

P := Wezel^.Prawy; Wezel^.Prawy := P^.Lewy; P^.Lewy := Wezel;

Wezel := P;

Wezel^.Lewy^.Licznik:= x1+x2;

Wezel^.Licznik:= Wezel^.Lewy^.Licznik+x3;

end;

procedure Obrot_PL(var Wezel : POsobaD);

var P : POsobaD; x1, x2, x3 : longint;

begin

x1:= 0; x2:= 0; x3:= 0;

if Wezel^.Prawy <> nil then x1:= Wezel^.Prawy^.Licznik;

if Wezel^.Lewy^.Prawy <> nil then x2:= Wezel^.Lewy^.Prawy^.Licznik;

if Wezel^.Lewy^.Lewy <> nil then x3:= Wezel^.Lewy^.Lewy^.Licznik;

P := Wezel^.Lewy; Wezel^.Lewy := P^.Prawy; P^.Prawy := Wezel;

Wezel := P;

Wezel^.Prawy^.Licznik:= x1+x2;

Wezel^.Licznik:= Wezel^.Prawy^.Licznik+x3;

end;

procedure Podzial(var Wezel : POsobaD; Liczba : integer);

var il : integer;

begin

if Wezel^.Lewy = nil then il :=0 else il:= Wezel^.Lewy^.Licznik;

if il > Liczba then begin

Podzial(Wezel^.Lewy, Liczba);

Obrot_PL(Wezel);

end else

if (il < Liczba) then begin

Podzial(Wezel^.Prawy, Liczba-il-1);

Obrot_LL(Wezel);

end;

end;

9.1.5. Przejście przez drzewo

(13)

10 11

4 15 5

7 8

10 11

4 15 5

7 8

10 11

4 15 5

7 8

10 11 4 15

5 7

8

10 11 4 15

5 7

8

10 11 4 15

5 7

8 10

11 4 15

5 7

8

10 11 4 15

5 7

8

10 11

4 15 5

7 8

10 11

4 15 5

7 8

10 11 4 15

5 7

8

10 11 4 15

5 7

8

10 11

4 15 5

7 8

10 11 4 15

5 7

8

10 11

4 15 5

7 8

10 11 4 15

5 7

8

10 11 4 15

5 7

8

10 11

4 15 5

7 8

10 11 4 15

5 7

8

10 11 4 15

5 7

8 10

11 4 15

5 7

1) 2) 3) 8

(14)

1) Przejście przedrostkowe przez drzewo

procedure Dla_kazdego(Wezel : POsobaD; funkcja: zrob);

begin

if Wezel <> nil then begin

funkcja(Wezel^.Dane);

Dla_kazdego(Wezel^.Lewy,funkcja);

Dla_kazdego(Wezel^.Prawy, funkcja) end;

end;

2) Przejście uporządkowane przez drzewo

procedure Dla_kazdego(Wezel : POsobaD; funkcja: zrob);

begin

if Wezel <> nil then begin

Dla_kazdego(Wezel^.Lewy,funkcja);

funkcja(Wezel^.Dane);

Dla_kazdego(Wezel^.Prawy, funkcja) end;

end;

3) Przejście przyrostkowe przez drzewo

procedure Dla_kazdego(Wezel : POsobaD; funkcja: zrob);

begin

if Wezel <> nil then begin

Dla_kazdego(Wezel^.Lewy,funkcja);

Dla_kazdego(Wezel^.Prawy, funkcja) funkcja(Wezel^.Dane);

end;

end;

(15)

program Drzewo_wywazone;

uses Crt, Rozne, Modul, MDrzewoW;

const Tab_menu : Lancuchy = ('1 : Wstawianie do korzenia drzewa ', '2 : Wstawianie jako lisc drzewa ', '3 : Usuwanie z drzewa',

'4 : Wyswietlenie elementu drzewa','5 : Wywazanie drzewa',

'6 : Wydruk drzewa', '7 : Usun drzewo', 'K/k - Koniec programu','','','');

type wstawianie= (do_korzenia, jako_lisc);

procedure Wstaw_do_drzewa(var Poczatek :POsobaD;Jak: wstawianie );

var Dana : Osoba; Nowy : POsobaD;

begin

Podaj_dane(Dana);

Nowy_Element_D(Nowy, Dana);

if Nowy = nil then exit;

if Jak = do_korzenia then Wstaw_Korzen(Poczatek, Nowy) else Wstaw(Poczatek, Nowy);

if Nowy <> nil then

Dla_jednego(Poczatek, Nowy^.Dane.Nazwisko, Wydruk_danych);

end;

function Klucz:lan;

var Pom: lan;

begin

repeat Write('Podaj nazwisko: '); Readln(Pom); until Pom <> '';

Klucz:= Pom;

end;

var Wybor, Z : char; Poczatek_D, Gdzie : POsobaD;

begin

ClrScr; Randomize; Inicjalizacja(Poczatek_D);

repeat

Menu(Tab_menu, 8, Wybor);

case Wybor of

'1' : Wstaw_do_drzewa(Poczatek_D, do_korzenia);

'2' : Wstaw_do_drzewa(Poczatek_D, jako_lisc);

'3' : Usun_element_drzewa(Poczatek_D, Klucz);

'4' : Dla_jednego(Poczatek_D, Klucz, Wydruk_danych);

'5' : begin Oblicz_wezly(Poczatek_D); Wywaz_Drzewo(Poczatek_D);end;

'6' : Dla_kazdego(Poczatek_D, Wydruk_danych);

'7' : begin Usun_drzewo(Poczatek_D); Poczatek_D := nil; end;

end;

Pauza(Z, False);

until Wybor = 'K'; end.

(16)

9.2. Złożoność obliczeniowa tablic, drzew i list

Typ struktury danych Przypadek najgorszy-N / Przypadek średni-Ś

i algorytmu wstawianie wyszukiwanie wybór

N Ś N Ś N

traf. chyb.

tablica uporządkowana

n n/2 n n/2 n/2 1

tablica nieuporządkowana

1 1 n n/2 n n lg n

lista uporządkowana

n n/2 n n/2 n/2 n

lista nieuporządkowana

1 1 n n/2 n n lg n

wyszukiwanie binarne (tablica)

n n/2 lg n lg n lg n 1

binarne drzewo poszukiwań

n lg n n lg n lg n n

drzewo czerwono-czarne

lg n lg n lg n lg n lg n lg n

Cytaty

Powiązane dokumenty

Graf dwudzielny to taki, którego wierzchołki da si e podzielić na dwa zbiory A i B takie, że , pomi edzy dwoma wierzchołkami z tego samego zbioru nie ma kraw , edzi.. Jeśli graf G

VII.4 Obroty brył sztywnych dookoła osi swobodnych... Jan Królikowski Fizyka

Poznanie i zrozumienie tych potężnych istot jakimi są drzewa, jest najlepszym sposobem, aby się z nimi zaprzyjaźnić, dbać o nie, a może w końcu po prostu dać im spokój i

Opracowanie: Grupa Gdyby, High Grade KONCEPCJA PROJEKT KONCEPCYJNY „GRAJĄCE DRZEWO”. MATERIAŁY

Jedną z zasad, którą kierujemy się na tym etapie pracy, jest to, by nasze pytanie nie „opierało się na problemie”.. Nie dotyczyło narkotyków, przemocy

[...] Gdy muzyka przestała znajdować się w centrum naszego życia, wszystko się zmieniło: jako ornament ma być przede wszystkim «ładna», a w żadnym wypadku

Podzielmy prostokąt ABCD na cztery mniejsze prostokąty prostymi przechodzącymi przez punkt P (rys. Każdy z otrzymanych mniejszych prostokątów możemy podzielić przekątną na

k-elementowe kombinacje ze zbioru n-elementowego nie istotna kolejność SCHEMAT BERMULIEGO: P(k) = (n/k)p^(k)q^(n-k) Pewne doświadczenie wykonujesz n razy nie zależnie