• Lenguaje

    Pascal

  • Descripción

    Implementa la estructura de datos de tipo ábol binario.
    Inserta y elimina cadenas de caracteres al árbol.
    Balancea el árbol. Muestra gráficos en preorden, inorden y postorden.
    También muestra propiedades del árbol como altura, número de nodos, si está completo y si está balanceado.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
program prog_arbol;
uses crt, dos;

type Sentido = (IZQUIERDA, CENTRO, DERECHA);

type Arbol = ^TDAArbol;
TDAArbol = record
    izq, der : Arbol;
    cadena : string;
end;

function arbol_insertar (nodo : Arbol; cadena : string) : Arbol;
    begin
        if nodo = nil then
            begin
                new (nodo);
                nodo^.izq := nil;
                nodo^.der := nil;
                nodo^.cadena := cadena;
            end
        else
            if cadena < nodo^.cadena then
                nodo^.izq := arbol_insertar (nodo^.izq, cadena)
            else
                nodo^.der := arbol_insertar (nodo^.der, cadena);
        arbol_insertar := nodo;
    end;

function arbol_quitar_y_rotar (nodo : Arbol; cadena : string; rotacion : Sentido) : Arbol;
    var pivote : Arbol;
    begin
        if nodo <> nil then
            begin
                if nodo^.cadena = cadena then
                    begin
                        if nodo^.izq = nil then
                            pivote := nodo^.der
                        else if nodo^.der = nil then
                            pivote := nodo^.izq
                        else if rotacion = IZQUIERDA then
                            begin
                                pivote := nodo^.izq;
                                while pivote^.der <> nil do
                                    pivote := pivote^.der;
                                pivote^.der := nodo^.der;
                                pivote := nodo^.izq;
                            end
                        else
                            begin
                                pivote := nodo^.der;
                                while pivote^.izq <> nil do
                                    pivote := pivote^.izq;
                                pivote^.izq := nodo^.izq;
                                pivote := nodo^.der;
                            end;
                        dispose (nodo);
                        nodo := pivote;
                    end
                else if cadena < nodo^.cadena then
                    nodo^.izq := arbol_quitar_y_rotar (nodo^.izq, cadena, rotacion)
                else
                    nodo^.der := arbol_quitar_y_rotar (nodo^.der, cadena, rotacion);
            end;
        arbol_quitar_y_rotar := nodo;
    end;

function arbol_quitar (nodo : Arbol; cadena : string) : Arbol;
    begin
        arbol_quitar := arbol_quitar_y_rotar (nodo, cadena, IZQUIERDA);
    end;

procedure arbol_preorden (raiz : Arbol; nodo : Arbol);
    var pivote : Arbol;
    var hermanos : integer;
    var direccion : Sentido;
    var borde1, borde2 : char;
    begin
        if nodo <> nil then
            begin
                hermanos := 0;
                direccion := CENTRO;
                pivote := raiz;
                while pivote <> nodo do
                    begin
                        if (hermanos = 2) and (direccion = IZQUIERDA) then
                            write (#179' ')
                        else
                            write ('  ');
                        hermanos := 0;
                        if pivote^.izq <> nil then
                            inc (hermanos);
                        if pivote^.der <> nil then
                            inc (hermanos);
                        if nodo^.cadena < pivote^.cadena then
                            begin
                                pivote := pivote^.izq;
                                direccion := IZQUIERDA;
                            end
                        else
                            begin
                                pivote := pivote^.der;
                                direccion := DERECHA;
                            end;
                    end;
                if direccion = CENTRO then
                    borde1 := #196
                else if (hermanos = 1) or (direccion = DERECHA) then
                    borde1 := #192
                else
                    borde1 := #195;
                if (nodo^.izq <> nil) or (nodo^.der <> nil) then
                    borde2 := #194
                else
                    borde2 := #196;
                writeln (borde1, #196, borde2, nodo^.cadena);
                arbol_preorden (raiz, nodo^.izq);
                arbol_preorden (raiz, nodo^.der);
            end;
    end;

procedure arbol_inorden (raiz : Arbol; nodo : Arbol);
    var pivote : Arbol;
    var direccion : Sentido;
    var borde1, borde2: char;
    begin
        if nodo <> nil then
            begin
                direccion := CENTRO;
                arbol_inorden (raiz, nodo^.izq);
                pivote := raiz;
                while pivote <> nodo do
                    if nodo^.cadena < pivote^.cadena then
                        begin
                            if direccion = DERECHA then
                                write (#179' ')
                            else
                                write ('  ');
                            pivote := pivote^.izq;
                            direccion := IZQUIERDA;
                        end
                    else
                        begin
                            if direccion = IZQUIERDA then
                                write (#179' ')
                            else
                                write ('  ');
                            pivote := pivote^.der;
                            direccion := DERECHA;
                        end;
                case direccion of
                    IZQUIERDA: borde1 := #218;
                    CENTRO   : borde1 := #196;
                    DERECHA  : borde1 := #192;
                end;
                if (nodo^.izq <> nil) and (nodo^.der <> nil) then
                    borde2 := #197
                else if nodo^.izq <> nil then
                    borde2 := #193
                else if nodo^.der <> nil then
                    borde2 := #194
                else
                    borde2 := #196;
                writeln (borde1, #196, borde2, nodo^.cadena);
                arbol_inorden (raiz, nodo^.der);
            end;
    end;

procedure arbol_postorden (raiz : Arbol; nodo : Arbol);
    var pivote : Arbol;
    var hermanos : integer;
    var direccion : Sentido;
    var borde1, borde2 : char;
    begin
        if nodo <> nil then
            begin
                arbol_postorden (raiz, nodo^.izq);
                arbol_postorden (raiz, nodo^.der);
                hermanos := 0;
                direccion := CENTRO;
                pivote := raiz;
                while pivote <> nodo do
                    begin
                        if (hermanos = 2) and (direccion = DERECHA) then
                            write (#179' ')
                        else
                            write ('  ');
                        hermanos := 0;
                        if pivote^.izq <> nil then
                            inc (hermanos);
                        if pivote^.der <> nil then
                            inc (hermanos);
                        if nodo^.cadena < pivote^.cadena then
                            begin
                                pivote := pivote^.izq;
                                direccion := IZQUIERDA;
                            end
                        else
                            begin
                                pivote := pivote^.der;
                                direccion := DERECHA;
                            end;
                    end;
                    if direccion = CENTRO then
                        borde1 := #196
                    else if (hermanos = 1) or (direccion = IZQUIERDA) then
                        borde1 := #218
                    else
                        borde1 := #195;
                    if (nodo^.izq <> nil) or (nodo^.der <> nil) then
                        borde2 := #193
                    else
                        borde2 := #196;
                writeln (borde1, #196, borde2, nodo^.cadena);
            end;
    end;

function arbol_altura (nodo : Arbol) : integer;
    var izq, der : integer;
    begin
        if nodo = nil then
            arbol_altura := 0
        else
            begin
                izq := arbol_altura (nodo^.izq);
                der := arbol_altura (nodo^.der);
                if izq > der then
                    arbol_altura := 1 + izq
                else
                    arbol_altura := 1 + der;
            end;
    end;

function arbol_balancear (nodo : Arbol) : Arbol;
    var diferencia : integer;
    var cadena : string;
    begin
        if nodo <> nil then
            begin
                nodo^.izq := arbol_balancear (nodo^.izq);
                nodo^.der := arbol_balancear (nodo^.der);
                diferencia := arbol_altura(nodo^.izq) - arbol_altura(nodo^.der);
                if (diferencia > 1) or (diferencia < -1) then
                    begin
                        cadena := nodo^.cadena;
                        if diferencia > 1 then
                            nodo := arbol_quitar_y_rotar (nodo, cadena, DERECHA)
                        else
                            nodo := arbol_quitar_y_rotar (nodo, cadena, IZQUIERDA);
                        nodo := arbol_balancear (arbol_insertar (nodo, cadena));
                    end;
            end;
        arbol_balancear := nodo;
    end;

function arbol_nodos (nodo : Arbol) : integer;
    begin
        if nodo = nil then
            arbol_nodos := 0
        else
            arbol_nodos := 1 + arbol_nodos (nodo^.izq) + arbol_nodos (nodo^.der);
    end;

function arbol_completo (nodo : Arbol) : boolean;
    begin
        arbol_completo := (nodo = nil) or (
            (arbol_nodos (nodo^.izq) = arbol_nodos (nodo^.der)) and
            arbol_completo (nodo^.izq) and
            arbol_completo (nodo^.der));
    end;

function arbol_balanceado (nodo : Arbol) : boolean;
    var diferencia : integer;
    begin
        if nodo = nil then
            arbol_balanceado := true
        else
            begin
                diferencia := arbol_altura (nodo^.izq) - arbol_altura (nodo^.der);
                arbol_balanceado := (diferencia >= -1) and (diferencia <= 1) and
                    arbol_balanceado (nodo^.izq) and arbol_balanceado (nodo^.der);
            end;
    end;

var raiz : Arbol;
var opcion, tecla : char;
var cadena : string;
begin
    raiz := nil;
    repeat
        clrscr;
        writeln ('MEN'#233);
        writeln ('1.- Insertar cadena');
        writeln ('2.- Quitar cadena');
        writeln ('3.- Listado en preorden');
        writeln ('4.- Listado en inorden');
        writeln ('5.- Listado en postorden');
        writeln ('6.- Balancear');
        writeln ('7.- Consultar propiedades');
        writeln ('8.- Salir'#10#13);
        write ('Seleccione una opci'#162'n: ');
        repeat
            opcion := readkey;
        until (opcion >= '1') and (opcion <= '8');
        writeln (opcion, #10#13);
        if (raiz = nil) and (opcion <> '1') and (opcion <> '7')  and (opcion <> '8') then
            writeln ('El '#160'rbol est'#160' vac'#161'o.')
        else case opcion of
            '1':
                begin
                    write ('Ingrese el cadena a insertar: ');
                    readln (cadena);
                    raiz := arbol_insertar (raiz, cadena);
                    writeln (#10#13'Cadena agregada correctamente.');
                end;
            '2':
                begin
                    write ('Ingrese el cadena a quitar: ');
                    readln (cadena);
                    raiz := arbol_quitar (raiz, cadena);
                    writeln (#10#13'Cadena borrada correctamente.');
                end;
            '3': arbol_preorden  (raiz, raiz);
            '4': arbol_inorden   (raiz, raiz);
            '5': arbol_postorden (raiz, raiz);
            '6':
                begin
                    writeln (#181'rbol balanceado correctamente.');
                    raiz := arbol_balancear (raiz);
                end;
            '7':
                begin
                    writeln ('Altura    : ', arbol_altura(raiz));
                    writeln ('Nodos     : ', arbol_nodos (raiz));
                    writeln ('Completo  : ', arbol_completo  (raiz));
                    writeln ('Balanceado: ', arbol_balanceado(raiz));
                end;
        end;
        if opcion <> '8' then
            begin
                write (#10#13'Presione una tecla para continuar . . . ');
                tecla := readkey;
            end
    until opcion = '8';
end.