programmazione mod. b - alberi - prof. e. burattini 1

102
Programmazione Mod. B - A lberi - prof. E. Burattin i 1

Upload: niccolo-smith

Post on 01-May-2015

227 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

1

Page 2: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

2

A

B C

D

EF

5 3

15

2

1

20

3

A

B C

D

EF

5 3 2

1

3

Min(A-F) = {A,B,E,F} -->11 A

B C

D

EF

5 3

3

Min(A-D) = {A,B,E,F,C,D} -->14 A

B C

D

EF

5 3

15

2

1

20

3

A

B C

D

EF

5 3

15

2

1

20

3

I GRAFI

A

B C

D

EF

Page 3: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

3

A

B C

D

EF

5 3

15

2

1

20

3

A B C D E FA 5 20 15B 5 3 C 2 1D 20 2E 3 3F 15 1 3

DEF. Un albero è un grafo senza cicli o circuiti

A

B C

D

EF

5

151

20

3

A B C D E FA 5 20 15B 5 C 1D 20 E 3F 15 1 3

Page 4: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

4

GLI ALBERI COME STRUTTURE DATI

Search Tree - (Albero di ricerca) - Memorizza informazioni in maniera tale che possano essere ritrovate molto velocemente e le operazioni di inserimento e cancellazione nodi sono molto efficienti.

Page 5: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

5

Ricorsione lineare: al più una chiamata ricorsiva nell’ambito di uno stesso processo ricorsivo.

Ricorsione non lineare: più di una chiamata ricorsiva nell’ambito di uno stesso processo ricorsivo.

main

F(3)

F(1) F(2)

F(4)

F(2)

Fibonacci(4)

F(1) F(0)

F(1) F(0)

main

F(3)

F(1) F(2)

F(1) F(0)

Fibonacci(3)

FUNCTION Fibonacci(N:integer):integer;BEGIN IF N=0 THEN

Fibonacci:=0 ELSE IF N=1 THEN

Fibonacci:=1 ELSE

Fibonacci:= Fibonacci(N-2) + Fibonacci(N-1)END.

Page 6: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

6

Fibonacci(6)F(6)

F(5)F(4) +

F(2) F(3)+

F(2) F(1)+F(0)F(1) + 01 +

1 F(3)+

F(0)F(1) + 01 +

2

1 1+

3

F(3)

F(1)

F(2)

F(4)

F(5)

F(3)

F(6)

F(1) F(2)

F(3)

F(4)

F(2)

F(2)F(0)F(1)

F(0)

F(1)

F(0)F(1) F(1) F(0)F(0)F(1)

fibon1

Page 7: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

7

ALBERI BINARI

• Un albero è binario se ogni nodo è al più collegato ad altri due

• Un albero binario è:

– L’albero vuoto

– oppure è costituito da una radice e da un sottoalbero sinistro e da un sottoalbero destro

• L’albero è una struttura ricorsiva non lineare.

• I suoi elementi sono detti nodi

Page 8: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

8

I due disegni rappresentano due alberi uguali ma due alberi binari diversi.

L’ovvio modo di rappresentare un albero consiste nell’assegnare ad ogni nodo due puntatori uno che punta al sottoalbero sinistro ed uno che punta al sottoalbero destro.

Page 9: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

9

Per gestire gli alberi introduciamo un elemento costituito da nodi non più con uno ma con due campi per i puntatori. Attraverso questa struttura potremo rappresentare gli alberi di ricerca binari.

Albero Binario

Radice (root)

Sotto albero

Page 10: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

10

Ugo

CarloGiulio

Emma Guido Carla Maria

Anna Peppe Angela Nicola

Page 11: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

11

Definiamo sotto albero ogni nodo in cui almeno un puntatore non è uguale a NIL ma punta ad un altro nodo o sotto albero.

Definiamo radice di un sotto albero quel nodo che punta ad almeno un altro nodo (NB Negli alberi binari si può al massimo puntare a due nodi (destro e sinistro).

La variabile dinamica albero può essere definita attraverso la sua radice, il nodo a partire dal quale si possono raggiungere tutti gli altri nodi della struttura.

XXX

Tree

Left Structure Right Structure

Un albero (sotto albero), che punta a NIL e cioè non contiene nodi è detto albero (sotto albero) vuoto.

Page 12: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

12

Albero Binario

Radice (root)

Sotto albero

Cammino(path)

X

Genitore

Figlio

Livello del nodo X = 3

Nodi fratelli

Altezza dell’albero= Massimo numero di livelliH=3

Foglie

Page 13: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

13

Un albero binario è ordinato quando il campo chiave di ogni

nodo è minore del campo chiave di ogni nodo del suo

sottoalbero destro ed è maggiore del campo chiave di ogni

nodo del suo sottoalbero sinistro. Si parla in questo caso anche

di binary search tree (BST).

Page 14: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

14

Sergio

Toni

Luigi UgoAnna

Dora

Giulio

RiccardoGuido

Maria

Un albero binario di ricerca (BST) è tale se:- le foglie sinistre hanno un valore del campo chiave inferiore del nodo padre- le foglie destre hanno un valore del campo chiave maggiore del nodo padre

Campo chiaveKey FieldLeft Right

Roberto

Page 15: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

15

CONST

NullKey= ’un simbolo o valore per indicare NIL ' ;

NullInfo=‘quando possibile assegna un significato al nodo NIL’

TYPE

KItemType= STRING[20]

InfoType= un data type per le informazioni non key

BSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD

Key:KItemType;

Info: InfoType;

Left,

Right: BSTP

END;

VAR

TNode:BSTP;

Left Key Info Right

TNode

Page 16: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

16

Le operazioni che ci interessa definire sono:

•creazione di un nuovo nodo con un valore assegnato ai campi dati (Key e Info) e NIL

ai campi link (Left e Right)•dispose (dealloca) di un nodo supposto che esso esista come variabile dinamica

•selezionare un nodo data una chiave•selezionare le Info collegate al nodo

•selezionare il figlio a sinistra di un dato nodo•selezionare il figlio a destra di un dato nodo

Left Key Info Right

TNode

Page 17: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

17

INTERFACE

PROCEDURE MakeTNode(KeyValue:KItemType; TheInfo:InfoType; VAR TNode:BSTP);{ Crea un nuovo nodo, assegnando a KeyValue e TheInfo un valore e il valore NIL per i campi Left e Right }

PROCEDURE KillTNode(VAR TNode: BSTP);{dispose la memoria allocata per il TNode e poi pone il TNode a NIL. }

PROCEDURE GetNodesKey(TNode:BSTP; VAR TheKey:KItemType);{ritorna il key field del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullKey}

PROCEDURE GetNodesInfo(TNode:BSTP; VAR TheInfo:InfoType);{ritorna le informazioni del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullInfo}

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPE

KItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType; Left, Right: BSTP END;

VARTNode:BSTP;

Left Key Info Right

TNode

Page 18: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

18

FUNCTION NodesLeftTree(TNode:BSTP) : BSTP;{ritorna il puntatore al sotto albero sinistro di Tnode. Se T Node è NIL allora ritorna NIL }

FUNCTION NodesRightTree(TNode:BSTP) : BSTP;{ritorna il puntatore al sotto albero destro di Tnode. Se T Node è NIL allora ritorna NIL }

Left Key Info Right

TNode

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPE

KItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType; Left, Right: BSTP END;

VARTNode:BSTP;

Page 19: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

19

PROCEDURE MakeTNode(KeyValue:KItemType; TheInfo:InfoType; VAR TNode:BSTP);{ Crea un nuovo nodo, assegnando a KeyValue e TheInfo un valore e il valore NIL per i campi Left e Right }BEGIN

new(Tnode);WITH TNode^ DO BEGIN

Key:=KeyValue;Info:=TheInfo;Left:=NIL;Right:=NIL

ENDEND;

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 20: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

20

PROCEDURE KillTNode(VAR TNode :BSTP);{dispose la memoria allocata per il TNode e poi pone il TNode a NIL. }BEGIN

IF Tnode <> NIL THEN BEGIN

dispose(TNode);Tnode:=NIL

ENDEND;

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 21: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

21

PROCEDURE GetNodesKey(TNode:BSTP; VAR TheKey:KItemType);{ritorna il key field del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullKey}BEGIN

IF TNode <> NIL THEN TheKey:= TNode ^.KeyELSE TheKey:= NullKey

END;

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 22: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

22

PROCEDURE GetNodesInfo(TNode:BSTP; VAR TheInfo:InfoType);{ritorna le informazioni del nodo puntato da Tnode, se Tnode è NIL allora ritorna il valore di NullInfo}BEGIN

IF TNode <> NIL THEN TheInfo:= TNode ^.InfoELSE TheKey:= NullInfo

END;

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 23: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

23

FUNCTION NodesLeftTree(TNode:BSTP) : BSTP;{ritorna il puntatore al sotto albero sinistro di Tnode. Se T Node è NIL allora ritorna NIL }BEGIN

IF Tnode <> NIL THEN NodesLeftTree:=Tnode^.LeftELSE NodesLeftTree:=NIL

END:

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 24: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

24

FUNCTION NodesRightTree(TNode:BSTP) : BSTP;{ritorna il puntatore al sotto albero destro di Tnode. Se T Node è NIL allora ritorna NIL }BEGIN

IF Tnode <> NIL THEN NodesRightTree:=Tnode^. RightELSE NodesRightTree:=NIL

END:

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

Left Key Info Right

TNode

Page 25: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

25

Pseudo codice per un algoritmo generalizzato di selezione nodi

PROCEDURE GetNodeField(ANode:NodeP; VAR FieldVar: FieldType)

IF ANode <> NIL THENFieldVar ANode^.identificatore della variabile di campo selezionata

ELSE FieldVar NullValue

Page 26: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

26

Gli stessi dati possono essere contenuti in alberi binari di forma diversa.

Ugo

ToniMaria

Anna

Dora

SergioGiulio

Guido

Luigi Riccardo

Anna

Dora

Sergio

Giulio

Luigi

Guido

Maria

Riccardo

Toni

Ugo

Sergio

Toni

Luigi UgoAnna

Dora

Giulio

RiccardoGuido

Maria

Page 27: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

27

Un albero si dice bilanciato se il livello di tutte le foglie è uguale all’altezza dell’albero o a questa stessa altezza meno 1.

H=3

L=3

Foglie

H=3

L=3

L=2

Page 28: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

28

H=5

FoglieL=3

L=2

L=4

L=5

L=1

L=0

Page 29: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

29

Un albero bilanciato si esplora per fare una ricerca in un numero di passi inferiore a quello necessario per esplorare un albero non bilanciato. Nell’esempio supponiamo di cercare Riccardo:

Ugo

ToniMaria

Anna

Dora

SergioGiulio

Guido

Luigi Riccardo

Anna

Dora

Sergio

Giulio

Luigi

Guido

Maria

Riccardo

Toni

Ugo

Sergio

Toni

Luigi UgoAnna

Dora

Giulio

RiccardoGuido

Maria

Roberto

4 passi di computazione

2 passi di computazione

6 passi di computazione

Page 30: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

30

In un albero bilanciato il tempo massimo di ricerca è di O(log2 (N))

dove N è il numero di nodi.

Se un albero bilanciato ha M livelli, il numero di nodi di cui è

formato può variare tra

2M e 2(M+1) -1.

Page 31: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

31

ALBERO BILANCIATO CON M LIVELLI

Totale Nodi

N°NODI

1M2

02

12

1

1

0

21M

i

i

N°NODI

0

1

MM2

02

12

Totale Nodi

M

i

i

0

2

Page 32: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

32

M

i

iM

i

i N0

1

0

221

x

xaax

MM

i

i

1

)1( 1

0

Serie geometrica

1a 2x

1221

)21(2 1

1

0

M

MM

i

i

12121 1 MM N

122 1 MM N

Page 33: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

33

Supponiamo sia assegnata una lista di N oggetti tra i quali esiste una relazione d’ordine.Se riusciamo a inserire questi oggetti in un albero di ricerca bilanciato allora il numero di passi per trovare un qualunque oggetto è limitato da O(log2(N)).Se questo non avviene il caso peggiore in cui possiamo trovarci è pari a O(N).

Si può dimostrare che un albero di ricerca binario costruito in maniera casuale, quindi non necessariamente bilanciato, effettua in media un numero di passi per effettuare la ricerca pari a 1.36 * O(log2(N)).

Toni

Maria

Ugo

Riccardo

Anna

Dora

Sergio

Giulio

Luigi

Guido

N O(N) LOG(N) 1,36*LOG(N)1.000 1.000 9,97 14

1.000.000 1.000.000 19,93 27100.000.000 100.000.000 26,58 36

Page 34: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

34

ESEMPIOSupponiamo di avere un albero di tipo BST, chiamiamo con Root il primo nodo.Scrivere una funzione LeftMost che fornisca il puntatore del nodo più a sinistra che si incontra a partire da Root.

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Left Key Info Right

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

VAR Root:BSTP;

Root

Page 35: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

35

CONSTNullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

VAR Root:BSTP;

FUNCTION LeftMost(Root: BSTP): BSTP;

VARNodoEsaminato:BSTP;

BEGINIF EmptyTree(Root) THEN NodoEsaminato = NIL;ELSE NodoEsaminato = Root;

WHILE NodesLeftTree(NodoEsaminato) <> NIL DO NodoEsaminato = NodesLeftTree(NodoEsaminato) ;

LeftMost: = NodoEsaminatoEND:

Definizione della funzione

Definizione delle variabili

Verifica se l’albero è vuoto

Cerca il nodo

FUNCTION NodesLeftTree(TNode:BSTP) : BSTP;BEGIN

IF Tnode <> NIL THEN NodesLeftTree:=Tnode^.LeftELSE NodesLeftTree:=NIL

END:

Page 36: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

36

{ Dato un albero binario calcolare il puntatore dell'ultimo nodo a sinistra.}

Program AlberoSin(input,output);uses Crt, Alberi0;CONSTvar Albero,: BSTP;

FUNCTION ChiaveNodiSin(Tree:BSTP):BSTP;BEGINIF EmptyTree(NodesLeftTree(Tree)) THEN ChiaveNodiSin:=Tree ELSE

BEGINChiaveNodiSin:=ChiaveNodiSin(NodesLeftTree(Tree));END;

END;

{************** MAIN***********}beginwriteln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln(' La chiave e'' ', ChiaveNodiSin(Albero)^.Key);end.

Page 37: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

37

OPERAZIONI SUI BST

Ogni nodo di un BST punta ad altri due nodi, ciascuno dei quali è una variabile dinamica di tipo record.Quindi una variabile di tipo BSTType, cioè un puntatore alla radice di un BST, che è a sua volta una variabile BST, può essere passata da un blocco ad un altro. In altre parole dato un nodo di un BST, questo è radice per i suoi sottoalberi e i nodi a cui punta sono a loro volta radici di altri sottoalberi. Pertanto possiamo adoperare ricorsivamente queste variabili.

Poiché una variabile BST può essere interpretata o come nodo di un BST o come un sotto albero di un BST, pur essendo variabili dello stesso tipo parleremo nel primo caso di un tipo BSTP (puntatore a un nodo) e nel secondo caso di un tipo BSTType (puntatore a un albero) CONST

NullKey= ’un simbolo o valore per indicare NIL ' ;NullInfo=‘quando possibile assegna un significato al nodo NIL’TYPEKItemType= STRING[20]InfoType= un data type per le informazioni non keyBSTP=^BSTNode {puntatore a un nodo}

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left, Right: BSTP END;

BSTType=BSTPVARNomeAlbero:BSTTypeNodo:BSTP;

Left Key Info Right

NomeAlbero

Page 38: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

38

INTERFACE

PROCEDURE MakeTree(VAR Tree: BSTType);{inizializza a NIL l’albero, creando un albero vuoto}

PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean);{aggiunge un nodo all’albero rispettando la struttura di un BST, se il KeyValue è già presente nell’albero non fa nulla e Done risulta False}

PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean);

{elimina il nodo con chiave KeyValue, se esso non esiste Done risulta False}

FUNCTION SearchTNode(Tree: BSTType; KeyValue:KItemType): BSTP;{cerca il nodo con chiave KeyValue, se esso non esiste ritorna NIL}

FUNCTION EmptyTree(Tree: BSTType): boolean;{ritorna vero se l’albero è vuoto}

Page 39: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

39

IMPLEMENTATION

PROCEDURE MakeTree(VAR Tree: BSTType);{inizializza a NIL l’albero, creando un albero vuoto}BEGIN

Tree:=NILEND;

FUNCTION EmptyTree(Tree: BSTType): boolean;{ritorna vero se l’albero è vuoto} BEGIN

EmptyTree:=Tree=NILEND;

Page 40: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

40

ESEMPIO: COSTRUZIONE DI UN BST DI NOMI

Left Key Info Right

TNode

CONSTNullKey= ’ ' ;NullInfo=‘ ’TYPEKItemType= STRING[20]InfoType= STRING[20] BSTP=^BSTNode {puntatore a un nodo} BSTNode = RECORD {variabile dinamica per un nodo} Key:KItemType;

Info: InfoType;Left, {radice del sottoalbero di sinistra}

Right: BSTP {radice del sottoalbero di destra} END;

BSTType=BSTP; {definizione per la variabile albero} VAR

NameTree:BSTType;

Page 41: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

41

COSTRUZIONE DI UN BST DI NOMI

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

MariaGiulioSergioDora GuidoRiccardoToniAnnaRobertoreturn

Supponiamo che vengano introdotti da tastiera i seguenti nomi:

Page 42: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

42

Pseudo codice

MakeTree(NameTree)introduci NomeWHILE Nome <> NullKey DO

AddTNode(Nome, NullInfo, NameTree, Success)IF NOT Success THEN

segnala che il Nome esiste giàintroduci il nome

mostra il messaggio di fine lavoro

Page 43: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

43

CONSTNullKey= ’ ' ;NullInfo=‘ ’TYPEKItemType= STRING[20]InfoType= STRING[20] BSTP=^BSTNode

BSTNode = RECORD Key:KItemType;

Info: InfoType;Left,

Right: BSTP END;

BSTType=BSTP;VAR

NameTree:BSTTYpe;

PROCEDURE BuildNameTree(VAR NameTree: BSTType);{costruisce un albero a cui assegna un Nome dato in input}VAR

Nome:KItemType;Success: boolean;

BEGINMakeTree(NameTree);write(‘ Dammi un nome : ‘);readln(Nome);WHILE Nome <> NullKey DO BEGIN AddTNode(Nome, NullInfo, NameTree, Success); IF NOT Success THEN

writeln( Nome, ‘ esiste già’); write(‘ Dammi un nome : ‘); readln(Nome) END;

writeln(‘ L’albero è stato piantato’);END;

Page 44: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

44

DEFINIZIONE DIATTRAVERSAMENTO DI UN BST

Visitare tutti i nodi di un BST di nomi, a partire dalla radice, e elencare i nomi in ordine crescente (o decrescente).

AnnaDoraGiulioGuidoMariaRiccardoRobertoSergioToni

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Page 45: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

45

MOSTRA IL CONTENUTO DI UN BST

Mostra le Chiavi (KeyItem) di tutti i nodi del sottoalbero sinistro di NameTree

Mostra la Chiave (KeyItem) della radice di NameTree

Mostra le Chiavi (KeyItem) di tutti i nodi del sottoalbero destro di NameTree

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

ShowTree(NodesLeftTree(NameTree));

GetNodesKey(NameTree, Nome);

Writeln(Nome)

ShowTree(NodesRightTree(NameTree));

Pseudo codice

Page 46: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

46

La procedura ShowTree(NameTree) è una procedura ricorsiva il cui caso base è rappresentato dall’albero vuoto (EmptyTree). In altre parole il processo di pop inizia non appena l’argomento di ShowTree(NameTree) è un albero vuoto.

PROCEDURE ShowTree(NameTree: BSTType);VAR

NodesKey: KItemType;BEGIN

IF NOT EmptyTree(NameTree) THEN BEGIN

ShowTree(NodesLeftTree(NameTree));

GetNodesKey(NameTree, Nome);

writeln(Nome)

ShowTree(NodesRightTree(NameTree));

END

END;

Page 47: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

47

PROGRAM WriteAlbero(Tree:BSTP); PROCEDURE Wa(Tree:BSTP;I:integer); VAR J:integer; BEGIN IF NOT EmptyTree(Tree) THEN BEGIN Wa(NodesRightTree(Tree),I+1); FOR J:=1 TO I DO write(' '); write(Tree^.Key); writeln; Wa(NodesLeftTree(Tree),I+1); END; END;{************* MAIN***********}BEGINIF NOT EmptyTree(Tree) THEN Wa(Tree,1)END;

EsercizioAnalizzare la seguente procedure ricorsiva e descrivere il suo comportamento con un esempio

Page 48: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

48

Ricorsione lineare: al più una chiamata ricorsiva nell’ambito di uno stesso processo ricorsivo.

Ricorsione non lineare: più di una chiamata ricorsiva nell’ambito di uno stesso processo ricorsivo.

main

F(3)

F(1) F(2)

F(4)

F(2)

Fibonacci(4)

F(1) F(0)

F(1) F(0)

main

F(3)

F(1) F(2)

F(1) F(0)

Fibonacci(3)

FUNCTION Fibonacci(N:integer):integer;BEGIN IF N=0 THEN

Fibonacci:=0 ELSE IF N=1 THEN

Fibonacci:=1 ELSE

Fibonacci:= Fibonacci(N-2) + Fibonacci(N-1)END.

Page 49: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

49

Fibonacci(6)F(6)

F(5)F(4) +

F(2) F(3)+

F(2) F(1)+F(0)F(1) + 01 +

1 F(3)+

F(0)F(1) + 01 +

2

1 1+

3

F(3)

F(1)

F(2)

F(4)

F(5)

F(3)

F(6)

F(1) F(2)

F(3)

F(4)

F(2)

F(2)F(0)F(1)

F(0)

F(1)

F(0)F(1) F(1) F(0)F(0)F(1)

fibon1

Page 50: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

50

RICERCA DI UN DATO SU UN BST

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Riccardo ?????????

Page 51: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

51

FUNCTION Binary (VAR Studenti: StudenteRecord; MatrCercata:StringaNome; Lo, Hi :integer) :integer

VARMid:integer;

BEGINIF Lo>Hi THEN Binary := 0ELSE BEGIN Mid (Lo+Hi) DIV 2 IF Studenti[Mid].Matr=MatrCercata THEN

Binary := Mid ELSE

IF Studenti[Mid].Matr<MatrCercata THEN Binary := Binary(Studenti, MatrCercata, Mid+1, Hi)ELSE Binary := Binary(Studenti, MatrCercata, Lo, Mid-1)

END;END;

CASE BASE 2

ESPRESSIONE RICORSIVA

CASE BASE 1

Page 52: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

52

FUNCTION SearchTNode(Tree: BSTType; KeyValue:KItemType): BSTP;{cerca il nodo con chiave KeyValue, se esso non esiste ritorna NIL}VAR

TheKey: KItemType;BEGIN

IF EmptyTree(Tree) THEN SearchTNode NILELSE BEGIN GetNodesKey(Tree, TheKey) IF TheKey = KeyValue THEN

SearchTNode Tree ELSE

IF KeyValue < TheKey SearchTNode SearchTNode(NodesLeftTree(Tree), KeyValue)ELSE SearchTNode SearchTNode(NodesRightTree(Tree), KeyValue)

ENDEND;

TheKey:= TNode ^.Key

NodesLeftTree:=Tnode^.Left

NodesLeftRight:=Tnode^. Right

Page 53: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

53

ESERCIZIO

Sia assegnato un albero binario, scrivere un algoritmo tale che sposti ogni figlio sinistro nel corrispondente figlio destro e viceversa.

A

B C

D E F

G H

A

C B

DF E

H G

Page 54: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

54

{ Scrivere un algoritmo che dato un albero binario lo trasformi invertendo i figli sinistro e destro di ogni nodo }

Program AlberoScambio(input,output);uses Crt, Alberi0;CONST NKey=-100;var Albero,Temp : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean;

PROCEDURE ScambiaNodi(Tree:BSTP);

BEGINIF NOT EmptyTree(Tree) THEN BEGIN ScambiaNodi(NodesLeftTree(Tree)); ScambiaNodi(NodesRightTree(Tree)); Temp:=Tree^.Left; Tree^.Left:= Tree^.Right; Tree^.Right:=Temp; END;END;

{************** MAIN***********}

beginclrscr; writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); readln; {scambia nodi} ScambiaNodi(Albero); writeln(' SCAMBIO '); WriteAlbero(Albero); writeln(' FINE'); readln;

end.

Page 55: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

55

AGGIUNTA DI UN DATO SU UN BST

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Rolando

Per aggiungere un nodo a un BST è necessario innanzitutto verificare che l’Item non esiste già, perché in tal caso il nodo non viene aggiunto. Se non esiste bisogna trovare la sua corretta posizione nell’albero, cioè il suo genitore e mettere poi i figli a NIL.

Page 56: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

56

PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done:boolean);{aggiunge una foglia all’albero rispettando la struttura di un BST, se il KeyValue è già presente nell’albero non fa nulla e Done risulta False}

PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean);

{elimina il nodo con chiave KeyValue ricostruendo la struttura BST. Se il Nodo non esiste Done risulta False}

Page 57: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

57

Pseudo Codice di AddTNode

Search(Tree, KeyValue, TNode, Parent)

IF NOT EmptyTree(TNode) THENDone FALSE

ELSEcrea e aggiungi un nuovo nodo come figlio del nodo ParentDone TRUE

Se il nodo che vogliamo inserire, avente un certo KeyValue, esiste, allora Tnode non è vuoto e

quindi non lo aggiungiamo altrimenti lo aggiungiamo

Cerca sull’albero Tree il puntatore (TNode) al nodo con KeyValue, se esiste ritorna anche il padre, Parent, del nodo cercato altrimenti TNode=NIL.

.

Page 58: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

58

PROCEDURE AddTNode(KeyValue:KItemType; TheInfo:InfoType;VAR Tree: BSTType; VAR Done: boolean);

VARTnode, Parent : BSTP; {deve valere NIL se il nodo esiste già}ParentsKey: KeyItemType; {genitore del nodo da aggiungere}

BEGINSearch(Tree, KeyValue, TNode, Parent)IF NOT EmptyTree(TNode) THEN {il nodo esiste già}

Done := FALSEELSE {crea e aggiungi un nuovo nodo come figlio del nodo Parent}

BEGIN IF EmptyTree(Parent) THEN {il nuovo nodo sarà la radice}

MakeTNode(KeyValue, TheInfo, Tree) ELSE

BEGIN GetNodesKey(Parent, ParentsKey); {puntatore di ParentsKey} IF ParentsKey > KeyValue THEN {il nuovo nodo va a left}

MakeTNode(KeyValue, TheInfo, Parent^.Left) ELSE {il nuovo nodo va a right}

MakeTNode(KeyValue, TheInfo, Parent^.Right) END; Done := TRUE END

END;

Page 59: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

59

SearchSearch(Tree, KeyValue, TNode, Parent)Obiettivo: cercare un cammino verso un determinato nodo dell’albero.Se il nodo non esiste ritorna NIL. Se esiste ritorna il puntatore al nodo individuato e quello di suo padre.

Pseudo Codice

Parent NIL {la root non ha genitori}

TNode Tree {la radice è il primo nodo esaminato}

GetNodesKey(TNode, NodesKey) {estrai la chiave del nodo in esame}

WHILE ci sono altri nodi da esaminare AND non si è ancora trovato il nodo DO

Parent TNode

Tnode il sottoalbero legato al KeyValue

GetNodesKey(TNode, NodesKey) {estrai la chiave del nodo in esame}

EmptyTree(TNode) NodesKey <> KeyValue

IF NodesKey > KeyValue THEN TNode radice del sottoalbero sinistroELSE TNode radice del sottoalbero destro

Il padre dell’ultimo nodo esaminatodurante la ricerca di KeyValue

Page 60: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

60

PROCEDURE Search(Tree: BSTT, KeyValue: KItemType, VAR TNode, Parent: BSTP);

VAR

NodesKey: KItemType;

BEGIN

Parent:= NIL; {la root non ha genitori}

Tnode:= Tree; {la radice è il primo nodo esaminato}

GetNodesKey(TNode, NodesKey); {estrai la chiave del primo nodo}

WHILE NOT EmptyTree(TNode) AND (NodesKey <> KeyValue) DO

BEGIN

Parent:= Tnode;

IF NodesKey > KeyValue THEN Tnode:= NodesLeftTree(TNode)

ELSE Tnode:= NodesRightTree(TNode);

GetNodesKey(TNode, NodesKey) {estrai la chiave del nodo in esame}

END

END;

Ricordarsi che GetNodesKey nel caso trovi NIL ritorna NullKey

Page 61: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

61

19

13 21

12 15

14 17

16 18

20 24

23 26

Aggiungi 17 Tnode NIL

Pseudo Codice

Parent NIL {la root non ha genitori}

TNode Tree {la radice è il primo nodo esaminato}

GetNodesKey(TNode, NodesKey) {estrai la chiave del nodo in esame}

WHILE ci sono altri nodi da esaminare AND non si è ancora trovato il nodo DO

Parent TNode

Tnode il sottoalbero legato al KeyValue

GetNodesKey(TNode, NodesKey) {estrai la chiave del nodo in esame}

Aggiungi 22

22

Tnode = NIL

BEGINSearch(Tree, KeyValue, TNode, Parent)IF NOT EmptyTree(TNode) THEN {il nodo esiste già}

Done := FALSEELSE {crea e aggiungi un nuovo nodo come figlio del nodo Parent} BEGIN IF EmptyTree(Parent) THEN MakeTNode(KeyValue, TheInfo, Tree) {il nuovo nodo sarà la radice} ELSE

BEGINGetNodesKey(Parent, ParentsKey);IF ParentsKey > KeyValue THEN {il nuovo nodo va a sinistra}

MakeTNode(KeyValue, TheInfo, Parent^.Left)ELSE {il nuovo nodo va a destra}

MakeTNode(KeyValue, TheInfo, Parent^.Right) END;Done := TRUEEND

END;

AddTNode

Search

Page 62: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

62

ESERCIZIO{Scrivere una procedura o funzione che assegnato un albero binario di interi e un livello Lev conti il numero num di tutti i nodi presenti in quel livello. }

19

13 21

12 15

14 17

16 18

20 24

23 26

22

lev

riga

Page 63: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

63T19, riga=0,

lev=3, num= 0

19

13 21

12 15

14 17

16 18

20 24

23 26

22

lev

riga procedure ContaLivello(Tree:BSTP; riga,lev:integer;VAR num:integer); BEGIN if not (emptytree(tree)) THENBEGINIF riga=lev THEN num:=num+1;IF riga<lev THENBEGIN ContaLivello(NodesLeftTree(tree)

riga+1,lev,num); ContaLivello(NodesRightTree(tree), riga+1,lev,num);END;END;END;

T13, riga=1,

lev=3, num= 0

T12, riga=2,

lev=3, num= 0

T15, riga=2,

lev=3, num= 0

T14, riga=3,

lev=3, num= 1

T17, riga=3,

lev=3, num= 2

T15, riga=2,

lev=3, num= 1

T15, riga=2,

lev=3, num= 2

T13, riga=1,

lev=3, num= 2

T21, riga=1,

lev=3, num= 2

T20, riga=2,

lev=3, num= 2

T24, riga=2,

lev=3, num= 2

T23, riga=3,

lev=3, num= 3

T26, riga=3,

lev=3, num= 4

T24, riga=2,

lev=3, num=4

T21, riga=1,

lev=3, num= 4

T19, riga=0,

lev=3, num= 2

T19, riga=0,

lev=3, num= 4

Page 64: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

64

ProblemaRealizzare una procedura che elimina il nodo con chiave KeyValue

Pseudo CodiceSearch(Tree, KeyValue, Candidate, Parent)GetNodesKey(Candidate, CandsKey)IF CandsKey <> KeyValue THEN

Done FALSEELSE

riorganizza l’albero dopo aver rimosso CandidateKillTNode(Candidate)Done TRUE

Ritorna la chiave CandsKey puntata da Candidate

Implica che se cerco di nuovo un nodo con chiave CandsKey non lo trovo e che l’albero che resta, deallocando il nodo Candidate, è ancora un BST

Page 65: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

65

Analizziamo il problema della riorganizzazione dell’albero una volta eliminato un nodo.

Caso a- il nodo da eliminare ha il sotto albero sinistro vuoto.

QQQ

RRR

Parent

Candidate

left right

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Caso b- il nodo da eliminare ha il sotto albero destro vuoto.La procedura è analoga alla precedente.

Eliminare Riccardo

Page 66: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

66

Pseudo Codice

IF EmptyTree(NodesLeftTree(Candidate)) THENLinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree)

ELSEIF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree)ELSE continua a riorganizzare l’albero

PROCEDURE LinkParent (OldChild, NewChild, Parent: BSTP;VAR Tree: BSTType);{riorganizza l’albero BST dopo l’eliminazione di un nodo}

QQQ

RRR

Parent

Candidate

left right

Page 67: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

67

Riassunto dei tipi di cancellazione

New

Old

Parent

Old

New

PROCEDURE DeleteTNode(KeyValue:KItemType;VAR Tree: BSTType; VAR Done:boolean);{elimina il nodo con chiave KeyValue ricostruendo la struttura BST. Se il Nodo non esiste Done risulta False}

Page 68: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

68

Nel caso in cui il Nodo da cancellare ha sia il sotto albero di sinistra che quello di destra allora si procede come segue:si sostituisce al nodo da cancellare o il nodo di valore maggiore del suo sottoalbero di sinistra o quello di valore minore del suo sotto albero di destra. Se questo nodo ha a sua volta un sottoalbero di destra e uno di sinistra ci si comporta nei suoi confronti come se fosse un nodo da cancellare e quindi si esegue la stessa procedura sopra descritta.

Nodo da cancellare

30

5

3

40

35

80

38

8

35

5

3

40

35

80

38

8

Page 69: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

69

PROCEDURE DeleteTNode(KeyValue: KItemType; VAR Tree:BSTType; VAR Done:boolean);VAR

Candidate, {puntatore al nodo candidato per la cancellatura}Parent, {puntatore al genitore del nodo candidato}OldCandidate :BSTP;CandsKey: KItemType:

BEGIN

Done:= TRUE

Search(Tree, KeyValue, Candidate, Parent);

GetNodesKey(Candidate, CandsKey);

IF CandsKey<> KeyValue THEN

Done:=FALSE

ELSE

IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree)ELSE IF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE GetNewCandidate(KeyValue, Candidate, Tree);

KillTNode(Candidate);END;

Fornisce il puntatore della Key da eliminare e quello del suo genitore. Se Candidate=NIL significa che la Key non c’è. Fornisce la chiave CandsKey di Candidate

Se il sottoalbero sinistro è vuoto collega il genitore di candidate con la radice del sotto albero destro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero destro.

Se il sottoalbero destro è vuoto collega il genitore di candidate con la radice del sotto albero sinistro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero sinistro.

Se nessuno dei sue sotto alberi è vuoto allora chiama GetNewCandidate

Non c’è niente da cancellare

Page 70: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

70

PROCEDURE LinkParent(OldChild, NewChild, Parent: BSTP; VAR Tree:BSTType);{collega il nodo genitore con il sottoalbero connesso al nodo da cancellare}BEGIN

IF Parent=NIL THEN {sostituiamo la root} Tree:= NewChildELSE IF OldChild = NodesLeftTree(Parent) THEN

Parent^.Left:=NewChild {sostituiamo al genitore il figlio sinistro} ELSE

Parent^.Right:=NewChild {sostituiamo al genitore il figlio destro}END;

New

Old

Parent

Old

New

Page 71: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

71

ProblemaRealizzare una procedura che elimina il nodo con chiave KeyValue

Pseudo CodiceSearch(Tree, KeyValue, Candidate, Parent)GetNodesKey(Candidate, CandsKey)IF CandsKey <> KeyValue THEN

Done FALSEELSE

riorganizza l’albero dopo aver rimosso CandidateKillTNode(Candidate)Done TRUE

Ritorna la chiave CandsKey puntata da Candidate

Implica che se cerco di nuovo un nodo con chiave CandsKey non lo trovo e che l’albero che resta, deallocando il nodo Candidate, è ancora un BST

Pseudo Codice

IF EmptyTree(NodesLeftTree(Candidate)) THENLinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree)

ELSEIF EmptyTree(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree)ELSE continua a riorganizzare l’albero

Page 72: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

72

RICAPITOLANDO

Search(Tree, Key, Candidate, Parent)fornisce il puntatore Candidate del node che ha chiave Key e il puntatore Parent come padre

a

b

Key=bCandidate=P(b)Parent=P(a)

LinkParent(Old, New, Parent, Tree)collega New con Parent eliminando OLD,se Parent=NIL, cioè Old=Tree è la radice allora mette New al posto di Old e quindi di Tree

Parent

New

Old

OldNew

Page 73: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

73

Pesudo codice di DeleteTNode(Key, Tree, Done)

Search(Tree, Key, Candidate, Parent) Fornisce il puntatore della Key da eliminare e quello del suo genitore. Se Candidate=NIL significa che la Key non c’è.

GetNodesKey(Candidate, CandsKey) Fornisce la chiave CandsKey di Candidate

IF CandsKey<> Key Se la chiave trovata e quella di partenza non corrispondono CandsKey=NIL allora esci

ELSE

Se il sottoalbero sinistro è vuoto collega il genitore di candidate con la radice del sotto albero destro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero destro.

Se nessuno dei due sotto alberi è vuoto allora chiama GetNewCandidate

Se il sottoalbero destro è vuoto collega il genitore di candidate con la radice del sotto albero sinistro. Se Parent=NIL, cioè si vuole cancellare la radice allora poni in Tree la radice del sotto albero sinistro.

Page 74: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

74

35

5

3

40

35

80

38

8

Nodo da cancellare

30

5

3

40

35

80

38

8

old

candidate

parent

Page 75: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

75

Pseudo Codice di GetNewCandidate

OldCandidate Candidate

Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate)

OldCandidate^.Key Candidate^.Key

CandsKey := Candidate^.Key;

Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent)

IF Parent = NIL THEN

LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree)

ELSE

LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree)

Ricerca OldCandidate a partire dal suo nodo destro con la conseguenza che trova il più piccolo di questo sottoalbero (Candidate) (Dummy vale NIL)

Sostituisci il nodo da cancellare con Candidate

Riprendi la chiave del nodo spostato

Cerca il più piccolo nodo del sottoalbero destro del nodo spostato a partire dalla sua primitiva posizione

Collega il sottoalbero destro con il padre del nodo spostato

Se il nodo da cancellare è la root e segue immediatamente il padre allora collega il sottoalbero destro con la root

Page 76: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

76

PROCEDURE GetNewCandidate(KeyValue: KItemType; VAR Candidate:BSTP; VAR Tree:BSTType);

VARDummy, {variabile ausiliare per la chiamata alla Search}Parent, OldCandidate :BSTP;CandsKey: KItemType:

BEGIN

OldCandidate := Candidate

Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate)

OldCandidate^.Info := Candidate^.Info ;

OldCandidate^.Key := Candidate^.Key;

CandsKey := Candidate^.Key;

Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent);

IF Parent= NIL THEN

LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree)

ELSE

LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree)

END;

Page 77: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

77

90

50 95

30

34

40

3615

93 98

10017

13

35

47

Search(Tree, KeyValue, Candidate, Parent)

GetNodesKey(Candidate, CandsKey);

IF CandsKey<> KeyValue THEN Done:=FALSE

ELSE

IF EmptyTree(NodesLeftTree(Candidate)) THEN LinkParent(Candidate, NodesRightTree(Candidate), Parent, Tree) ELSE IF EmptyRight(NodesRightTree(Candidate)) THEN LinkParent(Candidate, NodesLeftTree(Candidate), Parent, Tree) ELSE GetNewCandidate(KeyValue, Candidate, Tree);KillTNode(Candidate);Done:= TRUE

Cancellare il nodo 30

OldCandidate := Candidate

Search(NodesRightTree(OldCandidate), KeyValue, Dummy, Candidate)

OldCandidate^.Key := Candidate^.Key;

CandsKey := Candidate^.Key;

Search(NodesRightTree(OldCandidate), CandsKey, Dummy, Parent);

IF Parent = NIL THEN

LinkParent(Candidate,NodesRightTree(Candidate), OldCandidate, Tree)

ELSE

LinkParent(Candidate,NodesRightTree(Candidate), Parent, Tree)END;

P30

P4030 NIL P34

34

34

P40 34 P34 P363834

P34 P35 P36

GetNewCandidate(KeyValue, Candidate, Tree);

DeleteTNode(KeyValue, Tree, Done)

Page 78: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

78

45 30 60

25 35 55 65 23 27 33 37 53 57 63 67

21 24 26 28 31 34 36 38 51 54 56 58 61 64 66 68 cancella il nodo 45

45

6030

25 35 55 65

23 27 33 37 53 57 63 67

21 24 26 28 31 34 36 38 51 54 56 58 61 64 66 68

51

51 30 60

25 35 55 65 23 27 33 37 53 57 63 67

21 24 26 28 31 34 36 38 54 56 58 61 64 66 68

Page 79: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

79

Program AlberoProva(input,output);uses Crt, Alberi0;CONST NKey=-100;var Albero : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean;

{************** MAIN***********}beginclrscr; writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); Info:=33; writeln(' inserisci il nodo - per finire -100'); readln(chiave); WHILE Chiave<>NKey DO

BEGIN AddTNode(Chiave,Info, Albero,Done); write(' aggiungi il nodo - per finire -100 >>> '); readln(chiave); END; WriteAlbero(Albero); readln;

{cancella nodo}write(' cancella il nodo ');readln(chiave);DeleteTNode(Chiave , Albero,Done);IF DONE=FALSE THEN writeln(' il nodo',

Chiave,' non è nell''albero');WriteAlbero(Albero);readln;WriteAlbero(Albero);writeln;writeln(' FINE');readln;end.

albpr6

Page 80: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

80

PROCEDURE StampaAlbero(Tree : BSTP; riga,inizio,fine:integer);var medio: integer;BEGIN if not(emptytree(tree)) then begin medio:=(inizio+fine) div 2; gotoxy(medio,riga); GetNodesKey(tree,Item); write(Item); StampaAlbero(NodesLeftTree(tree),riga+1,inizio,medio); StampaAlbero(NodesRightTree(tree),riga+1,medio,fine); END;END;

PROCEDURE WriteAlbero(Tree:BSTP); PROCEDURE Wa(Tree:BSTP;I:integer); VAR J:integer; BEGIN IF NOT EmptyTree(Tree) THEN BEGIN Wa(NodesRightTree(Tree),I+1); FOR J:=1 TO I DO write(' '); write(Tree^.Key); writeln; Wa(NodesLeftTree(Tree),I+1); END;

1 1 80

Page 81: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

81

ALGORITMI DI ATTRAVERSAMENTO DI BST

Algoritmi di attraversamento di un albero:

LNR - (LeftNodeRight) - Attraversamento inorder Per ogni nodo1 - Visita il sottoalbero sinistro 2 - Visita il nodo root3 - Visita il sottoalbero destroNLR - (NodeLeftRight) - Attraversamento pre-order Per ogni nodo1 - Visita il nodo root2 - Visita il sottoalbero sinistro 3 - Visita il sottoalbero destro

LRN - (LeftRightNode) - Attraversamento post-order Per ogni nodo1 - Visita il sottoalbero sinistro 2 - Visita il sottoalbero destro3 - Visita il nodo root

Page 82: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

82

LNR - (LeftNodeRight) - Attraversamento ordinato Per ogni nodo1 - Visita il sottoalbero sinistro 2 - Visita il nodo3 - Visita il sottoalbero destro

PROCEDURE Traverse(Root)IF root <> NIL THEN

Traverse(Root^.Left) {visita tutti i nodi del sottoalbero sinistro}Visit(Root) Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro}

PROCEDURE ShowTree(NameTree: BSTType);VAR NodesKey: KItemType;BEGIN

IF NOT EmptyTree(NameTree) THEN BEGIN

ShowTree(NodesLeftTree(NameTree));

GetNodesKey(NameTree, Nome);

writeln(Nome)

ShowTree(NodesRightTree(NameTree));

END

END;

Page 83: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

83

PROCEDURE Traverse(Root)IF root <> NIL THEN

Visit(Root)Traverse(Root^.Left) {visita tutti i nodi del sottoalbero sinistro}Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro}

NLR - (NodeLeftRight) - Attraversamento pre-ordinato Per ogni nodo1 - Visita il nodo root2 - Visita il sottoalbero sinistro 3 - Visita il sottoalbero destro

PROCEDURE StampaAlbero(Tree : BSTP; riga,inizio,fine:integer);

var medio: integer;BEGIN if not(emptytree(tree)) then begin medio:=(inizio+fine) div 2; gotoxy(medio,riga); GetNodesKey(tree,Item); write(Item); StampaAlbero(NodesLeftTree(tree),riga+1,inizio,medio); StampaAlbero(NodesRightTree(tree),riga+1,medio,fine); END

Page 84: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

84

PROCEDURE Traverse(Root)IF root <> NIL THEN

Traverse(Root^.Left) {visita tutti i nodi del sottoalbero sinistro}Traverse(Root^.Right) {visita tutti i nodi del sottoalbero destro}Visit(Root)

LRN - (LeftRightNode) - Attraversamento post-ordinato Per ogni nodo1 - Visita il sottoalbero sinistro 2 - Visita il sottoalbero destro3 - Visita il nodo root

Page 85: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

85

ProblemaEliminare un BST senza lasciare spazzatura.

SoluzioneAttraversa l’albero con un algoritmo LRN (post-order) e cancella ogni nodo incontrato. E’ utilizzato l’LRN perché la root è sempre l’ultima ad essere deallocata dopo aver deallocato i nodi figli, e quindi nessun link è eliminato prima del dovuto.

PROCEDURE KillTree(VAR Tree:BSTType);BEGIN

IF NOT EmptyTree(Tree) THEN BEGIN

KillTree(NodesLeftTree(Tree);KillTree(NodesRightTree(Tree);KillTNode(Tree)

ENDEND; Sergio

Toni

Anna

Dora

Giulio

RiccardoGuido

Maria

Roberto

Page 86: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

86

ProblemaEspressioni aritmetiche.

Notazione Polacca Inversa 5 3 * 4 1 - /

Visita LRNpost-order

Notazione Polacca Diretta/ * 5 3 - 4 1

Visita NLRpre-order

/

*

5 3

-

4 1

Notazione infissa(5*3)/(4-1)

Visita LNRinorder

/

*

5 3

-

4 1

/

*

5 3

-

4 1

PROCEDURE Traverse(Root)IF root <> NIL THEN

Visit(Root)Traverse(Root^.Left)Traverse(Root^.Right)

PROCEDURE Traverse(Root)IF root <> NIL THEN

Traverse(Root^.LeftTraverse(Root^.Right) Visit(Root)

PROCEDURE Traverse(Root)IF root <> NIL THEN

Traverse(Root^.Left)Visit(Root)Traverse(Root^.Right)

Page 87: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

87

Program AlberoConta(input,output);uses Alberi0;CONST NKey=-100;var Albero,Temp : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; Cont:integer;

FUNCTION ContaNodiSinNul(Tree:BSTP):integer;VAR cont1:integer;BEGINIF EmptyTree(Tree) THEN ContaNodiSinNul:= 0 else

BEGIN IF NOT EmptyTree(NodesRightTree(Tree)) THEN ContaNodiSinNul:=ContaNodiSinNul(NodesRightTree(Tree));

IF NOT EmptyTree(NodesLeftTree(Tree)) THEN ContaNodiSinNul:=ContaNodiSinNul(NodesLeftTree(Tree)) ELSE ContaNodiSinNul:=ContaNodiSinNul(NodesRightTree(Tree))+1;

END;END;

{************** MAIN***********}beginwriteln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln('Ci sono ', ContaNodiSinNul(Albero),' nodi con sotto albero sinistro nullo');end.

ESERCIZIO{ Dato un albero binario calcolare quanti nodi hanno il sottoalbero sinistro nullo.}

ALBCONT2

Page 88: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

88

{ Scrivere un algoritmo che dato un albero binario scriva le chiavi in ordine prima crescente e poi decrescente }Program ScriviAlbero (input,output);uses Alberi0;CONST NKey=-100;var Albero : BSTP; Item, Chiave : KItemType; Info:InfoType; Done:boolean;PROCEDURE Crescente(Tree:BSTP);BEGINIF Not EmptyTree(Tree) THEN BEGIN

Crescente(NodesLeftTree(Tree)); write(' ',tree^.key);

Crescente(NodesRightTree(Tree));END;

END;PROCEDURE DeCrescente(Tree:BSTP);BEGINIF Not EmptyTree(Tree) THEN

BEGINDeCrescente(NodesRightTree(Tree));

write(' ',tree^.key);DeCrescente(NodesLeftTree(Tree));END;

END;

{************** MAIN***********}begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); writeln('crescente '); Crescente(Albero); writeln('decrescente '); DeCrescente(Albero);end.

Page 89: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

89

ESERCIZI

1- Scrivere una procedura che assegnato un albero binario di interi positivi non ordinato restituisca un puntatore al valore massimo e quante volte questo valore massimo è contenuto nell'albero.

ES2GEN04

2- Scrivere una procedura che assegnato un albero binario di interi positivi non ordinato e due numeri positivi N1 e N2 restituisca la quantità di numeri pari compresi tra N1 e N2.

ES2FEB04

3- Assegnato un albero non ordinato di interi scrivere una procedura ricorsiva che trasformi l'albero non ordinato in un albero BST. Determinare l'altezza dell'albero non ordinato e dell'albero BST.

ESN0N0R2

Page 90: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

90

uses Alberi0;CONST NKey=-100;VAR

Albero: BSTP;Cont:integer;

PROCEDURE ContaNodiNul(Tree:BSTP; VAR Conta:integer);BEGINIF NOT EmptyTree(Tree) THEN

BEGINContaNodiNul(NodesLeftTree(Tree),Conta);ContaNodiNul(NodesRightTree(Tree),Conta);IF (Tree^.Right=NIL) AND (Tree^.key MOD 2 <>0) THEN Conta:=Conta+1;END;

END;

{************** MAIN***********}BEGINwriteln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero);cont:=0;ContaNodiNul(Albero,Cont); writeln(' Ci sono ',cont,' nodi con sotto albero

destro nullo e padre dispari');END.

PROGRAM DispariNulli(input,output);{ Assegnato un albero BST di numeri interi, fornire una procedura ricorsiva che dica quanti nodi, la cui chiave è un numero dispari, hanno sottoalbero destro nullo..}

Page 91: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

91

ALBERO BILANCIATO CON M LIVELLI

Totale Nodi

N°NODI

1M2

02

12

1

1

0

21M

i

i

N°NODI

0

1

MM2

02

12

Totale Nodi

M

i

i

0

2

Page 92: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

92

ESERCIZIO{ Dato un albero binario non bilanciato costruire un albero

bilanciato.}

Da Albero a Vettore

Bilanciamento

Stampa

Non bilanciatobilanciato

Controllo bilanciamento

Page 93: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

93

Da Albero a Vettore

Bilanciamento

Stampa

Non bilanciato

bilanciato

Controllo bilanciamento

1

2

5

3

7

8

9

1

2

5

3 7

8

9

1 2 3 5 7 8 9

1 2 3 5 7 8 9

Page 94: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

94

FUNCTION UnisciAlberi(e:KItemType;a,b:BSTP) : BSTP;{crea un albero con chiave ‘e’ e sottoalbero sinistro ‘a’ e destro ‘b’ eventualmente anche vuoti }

VAR c:BSTP;

BEGINnew(c);c^.left:=a;c^.right:=b;c^.key:=e;

UnisciAlberi:=c;END;

e

x

a

y z

b

w

Page 95: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

95

Program Bilanciare(input,output);uses Alberi0;CONST NKey=-100;TYPE Vettore=ARRAY[1..40] OF integer;var Albero,Bilanciato : BSTP; Item: KItemType; Chiave:KItemType; Info:InfoType; Done:boolean; V:vettore; I,Vmax:integer;

FUNCTION vet2alb(vx:vettore;i,j:integer):BSTP;{a partire dal vettore V ordinato genero l'albero vet2alb}

PROCEDURE DaAlberoAVettore(A:BSTP;VAR V:vettore;VAR max:integer);{Dato un albero BST costruisce un vettore ordinato}

FUNCTION Bilancia(A:BSTP):integer;{Dato un albero controlla se è bilanciato, quasi-bilanciato o non bilancitao}

PROCEDURE ControllaBilanciamento(A:BSTP);

{************** MAIN***********}BEGIN writeln('Costruiamo un Albero. '); BuildNameTree(Albero); IF not ControlloBilanciamento(Albero) THEN BEGIN Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); writeln(ControlloBilanciamento(Bilanciato)); END ELSE writeln(' FINE');END.

Page 96: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

96

FUNCTION Bilancia(A:BSTP;VAR cmax,cmin:integer;livello:integer):integer;BEGINIF not EmptyTree(A) THENBEGINIF EmptyTree(NodesRightTree(A)) OR EmptyTree(NodesLeftTree(A)) THENBEGINIF cmax<livello THENcmax:=livello;IF cmin>livello THENcmin:=livello;END;bilancia:=bilancia(NodesRightTree(A),cmax,cmin,livello+1);bilancia:=bilancia(NodesleftTree(A),cmax,cmin,livello+1);END;Bilancia:=cmax-cminEND;

FUNCTION ControlloBilanciamento(A:BSTP):boolean;VAR cmx,cmn:integer;BEGINcmx:=0;cmn:=maxint; IF Bilancia(A,cmx,cmn,0)=0 Then BEGIN ControlloBilanciamento:=TRUE;writeln(' L''albero è bilanciato') END ELSE IF Bilancia(A,cmx,cmn,0)=1 Then BEGIN ControlloBilanciamento :=TRUE;writeln(' L''albero è quasi bilanciato') END ELSE BEGIN ControlloBilanciamento:=FALSE;writeln(' L''albero non è bilanciato'); END;END;

Page 97: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

97

PROCEDURE DaAlberoAVettore(A:BSTP;VAR V:vettore;VAR max:integer);VAR I:integer;BEGINIF NOT EmptyTree(A) THEN BEGIN DaAlberoAVettore(NodesLeftTree(A),V,max); Max:=max+1; V[max]:=Tree^.key; DaAlberoAVettore(NodesRightTree(A),V,max); END;END;

{************** MAIN***********}begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); ControllaBilanciamento(Albero); Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); ControllaBilanciamento(Bilanciato); writeln; writeln(' FINE'); readln;end.

Page 98: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

98

FUNCTION vet2alb(vx:vettore;i,j:integer):BSTP;{a partire dal vettore V ordinato genero l'albero vet2alb}VARK:integer;BEGINIF I>J THEN

Vet2alb:=NILELSE

IF I=J THENVet2alb:=UnisciAlberi(Vx[I],NIL,NIL)

ELSEBEGIN K:=(I+J) DIV 2; Vet2alb:=UnisciAlberi(Vx[K],vet2alb(Vx,I,K-1),vet2alb(vx,K+1,j))END;

END;

{************** MAIN***********}begin writeln('Costruiamo un Albero. '); BuildNameTree(Albero); WriteAlbero(Albero); ControllaBilanciamento(Albero); Vmax:=0; DaAlberoAVettore(Albero,V,Vmax); Bilanciato:=Vet2ALb(V,1,Vmax); ControllaBilanciamento(Bilanciato); writeln(' FINE');end.

ALBBIL3

FUNCTION UnisciAlberi(e:KItemType;a,b:BSTP) : BSTP;{crea un albero con chiave ‘e’ e sottoalbero sinistro ‘a’ e destro ‘b’ eventualmente anche vuoti }VAR c:BSTP;BEGIN

new(c);c^.left:=a;c^.right:=b;c^.key:=e;

UnisciAlberi:=c;END;

Page 99: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

99

UnisciAlberi(Vx[K],vet2alb(Vx,I,K-1),vet2alb(vx,K+1,j))

gfedcba

7654321

Vet2ALb(V,1,Vmax);

Vet2ALb(V,1,7); K=4

UnisciAlberi(Vx[4],vet2alb(Vx,1,3),vet2alb(vx, 5,7))

Vet2ALb(V,1,3); K=2

UnisciAlberi(Vx[2],vet2alb(Vx,1,1),vet2alb(vx, 3,3))

Vet2ALb(V,1,1); K=1 Vet2ALb(V,3,3); K=3a c

b

UnisciAlberi(Vx[4],vet2alb(Vx,1,3),vet2alb(vx, 6,7))

Vet2ALb(V,5,7); K=6

Vet2ALb(V,5,5); K=5 Vet2ALb(V,7,7); K=7e g

f

d

d

f

e gca

b

Page 100: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

100

ESERCIZIO LA FAMIGLIA

{calcola le parentele }

Descritte le parentele secondo un albero non ordinato scrivere le funzioni

FUNCTION Padre{dato un nome determinare se ha un padre e chi è}

PROCEDURE Figlio{dato un nome determinare se ha uno o due figli e chi sono}

FUNCTION Nonno {dato un nome determinare chi è il nonno}

FUNCTION Fratello{dato un nome determinare se ha un fratello e chi è}

FUNCTION Zio{dato un nome determinare se ha uno zio e chi è}

END;

Page 101: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

101

Esercizio .

Dato un albero determinare quanti nonni hanno un solo nipote.

Page 102: Programmazione Mod. B - Alberi - prof. E. Burattini 1

Programmazione Mod. B - Alberi - prof. E. Burattini

102