Erratas y Escolios EDyA v1.2

82
document.doc ESTRUCTURAS DE DATOS Y ALGORITMOS Posibles erratas que encontré y aclaraciones (escolios o marginalia, escritos en los márgenes) a las dudas que fueron surgiendo en el estudio del libro: 'Estructura de Datos y Algoritmos ' de R. Hernández, J.C. Lázaro, R. Dormido y S. Ros. Prentice Hall. Madrid 2001; libro de texto de la asignatura de mismo nombre. En cursiva y negrilla la localización en el texto de la errata o de lo comentado. Las partes sobre las que tengo dudas, aparecen resaltadas en amarillo. Ruego vuestra colaboración, lo mismo que para para la confirmación o refutación de las erratas . Si encuentras algún error, punto oscuro o quieres hacer un añadido, por favor, comunícamelo. Roberto Alonso Menlle Alumno Centro Asociado de Ceuta [email protected] Las entradas que han sufrido alguna modificación o que son nuevas respecto a la primera versión del documento (enviada a Tec-InFor en agosto 2001) va precedidas por el texto *añadido*. Si quieres localizarlos rápidamente, pica 'Edición' / 'Buscar...' y busca la cadena *añadido* Para poder seguir correctamente los bucles de los programas 3.7 (balanceada) y 3.8 (polifásica) en la última sección de este documento hice un 'copiar y pegar' de los fuentes del CD, editándolos para dejarlos tal como figuran en el libro de texto, añadiendo numeración de líneas y llaves de diferentes colores que abarcan los distintos bucles. Resultan prácticos si se imprimen y se pegan las hojas una a continuación de la otra para tener el programa completo de un solo vistazo. Los encabezados y pies de página están preparados para impresión a doble cara. Para imprimir en una sola, picar 'Archivo' / 'Configurar página...' , en la 'Pestaña Diseño de página' desmarcar la casilla 'Pares e impares diferentes' ÍNDICE ERRATAS 3 ESCOLIOS tema 1 15 tema 2 21 tema 3 37 tema 4 57 tema 5 65 tema 6 73 Página 1 de 86

description

erraas

Transcript of Erratas y Escolios EDyA v1.2

ESTRUCTURAS DE DATOS Y ALGORITMOS

Erratas y Escolios EDyA v1.2.docErratas y Escolios EDyA v1.2.doc

ESTRUCTURAS DE DATOS Y ALGORITMOS

Posibles erratas que encontr y aclaraciones (escolios o marginalia, escritos en los mrgenes) a las dudas que fueron surgiendo en el estudio del libro: 'Estructura de Datos y Algoritmos' de R. Hernndez, J.C. Lzaro, R. Dormido y S. Ros. Prentice Hall. Madrid 2001; libro de texto de la asignatura de mismo nombre.

En cursiva y negrilla la localizacin en el texto de la errata o de lo comentado.

Las partes sobre las que tengo dudas, aparecen resaltadas en amarillo. Ruego vuestra colaboracin, lo mismo que para para la confirmacin o refutacin de las erratas .Si encuentras algn error, punto oscuro o quieres hacer un aadido, por favor, comuncamelo.

Roberto Alonso Menlle

Alumno Centro Asociado de Ceuta

[email protected] entradas que han sufrido alguna modificacin o que son nuevas respecto a la primera versin del documento (enviada a Tec-InFor en agosto 2001) va precedidas por el texto *aadido*. Si quieres localizarlos rpidamente, pica 'Edicin' / 'Buscar...' y busca la cadena *aadido*

Para poder seguir correctamente los bucles de los programas 3.7 (balanceada) y 3.8 (polifsica) en la ltima seccin de este documento hice un 'copiar y pegar' de los fuentes del CD, editndolos para dejarlos tal como figuran en el libro de texto, aadiendo numeracin de lneas y llaves de diferentes colores que abarcan los distintos bucles. Resultan prcticos si se imprimen y se pegan las hojas una a continuacin de la otra para tener el programa completo de un solo vistazo.

Los encabezados y pies de pgina estn preparados para impresin a doble cara. Para imprimir en una sola, picar 'Archivo' / 'Configurar pgina...' , en la 'Pestaa Diseo de pgina' desmarcar la casilla 'Pares e impares diferentes'

NDICE

ERRATAS

3

ESCOLIOStema 1

11

tema 2

15

tema 3

27

tema 4

41

tema 5

47

tema 6

53

Addenda

55

Fuente prog. 3.7 (balanceada)57

Fuente prog. 3.8 (polifsica)

61.....Salto de pgina....

ERRATAS

TEMA 1

Pag 7. Segunda lnea.

Dice: Definicin 1.3; debe decir: Definicin 1.2.

Pag 7. Definicin 1.4.

Dice: {-1,-2,,(}; debe decir: {-1,-2,,-(}.

*aadido*

Pag 9. Principio del ltimo prrafo. Por Fran J. Carmona ([email protected])

Dice : (...) los nmeros reales no forman un conjunto ordenado al no ser numerable.

Debe decir: (...) los nmeros reales no forman un conjunto bien ordenado (con un orden bien fundado) al no ser numerable.

o bien: (...) los nmeros reales no forman un conjunto ordinal al no ser numerable.

Ver el escolio correspondiente.

Pag 15. Tercer prrafo.

Tal como es el ejemplo desarrollado (figura 1.3) slo es necesaria la sentencia Allocate(p,

SIZE(integer)). No se necesita reservar memoria para la variable referenciada por el puntero q, pues en el ejemplo la direccin contenida en q es la misma que p y por tanto la variable referenciada es la misma. Otra cosa sera si, por ejemplo, entre 3 y 4 queremos hacer p^ :=10, en cuyo caso s deberamos antes de ello escribir la sentencia Allocate(q,SIZE(integer)).

TEMA 2

Pag 51. ltima lnea.Dice: 2 + 3 +...+ n = 1 + 2 + ... + n 1;

debera decir: 2 + 3 +...+ n = (1 + 2 + ... + n) 1,

Para evitar leerlo como 2 + 3 +...+ n =1 + 2 + ... +(n 1), igualdad que es claramente falsa. No s si esta omisin de parntesis vulnera algn convenio notacional de series. Creo que s.

Pag 60. Mmax(if) = 1+ 3 + 5 + ...+n/2.

Esta expresin es errnea; la correcta es: Mmax(if) =(n-1) + (n-3) + (n-5) + ...+ (n-1)DIV(n DIV 2).

Ver comentario ms amplio en el escolio correspondiente.

Adems el resultado que pone para la suma (n2 / 4) es el valor aproximadamente- correcto de la serie correcta expuesta en el escolio pero no se corresponde a la serie del libro cuyo resultado sera (n2 + 2n) / 16 (nmero de elementos de esa serie: n/4)

Pag 64: Programa 2.4.Tal como est implementado el algoritmo, parte del texto que le sigue es errneo, as como el clculo del coste de las comparaciones. Si se realiza una pequea modificacin en el programa, el texto y los clculos pasaran a ser correctos. Las modificaciones propuestas, resaltadas en gris.

VAR

i,j,k: Tipo_indice;

aux: Tipo_datos;

BEGIN

k:=n-1; FOR i:=1 TO n-1 DO

FOR j:=1 TO k DO

IF a[j]>a[j+1] THEN (*comparar elementos contiguos*)

aux:=a[j+1]; (*intercambiar*)

a[j+1]:=a[j];

a[j]:=aux;

END;

END; (*del FOR interno*)

k:=k-1; END; (*del FOR externo*)

END;

Ver escolio correspondiente

Pag 66. Lnea 4 desde el final.

Dice: est marcada por los ndices L y R que ...

Debe decir: est marcada por los ndices L y R+1 que...Ver escolio.

Pag 68. Programa 2.5.Tal como est el programa, falla si se intenta ejecutar con un arreglo ya ordenado. Una posible mejora consiste en introducir la sentencia IF R>=1 THEN justo antes del segundo FOR y su END correspondiente antes del Until. En el escolio, el programa completo y la justificacin.

Pag 69. Tabla 2.1En las casillas Promedio y Mximo de la segunda fila

dice respectivamente: (n2+13n-14)/4(n2+5n-6)/2

debe decir: (n2+3n-4)/4

(n2+9n-10)/2.

Pag 75. Lnea 3 de 2.3.2.

Dice: para i = L,...,R/2

Debe decir: i = L,...,R DIV 2

Tambin sera muy recomendable poner un ( delante de la expresin anterior y sustituir la 'y' de esta lnea por un AND.

Pag 75. Lnea 8 desde el final.Dice: (9 DIV 2 + 1 = 5);

Debe decir: ((9 DIV 2) + 1 = 5)

Pag 76. Primera lnea.Dice: h2=14 > h4=9 y hay que intercambiarlo con h5=3.

Debera decir (o algo similar): h2=14 > h4=9 y h2=14 > h5=3 y hay que intercambiarlo con h5=3 por ser la menor.

*aadido*

Pag 76. Figura 2.10. Sealada por Antonio Linde ([email protected])

En el primer prrafo de texto dentro de la figura dice:

Dice: Se intercambia y se asegura que sigue siendo un montn, comprobando para i>1.

Debera decir algo similar a: Se intercambia y se asegura recursivamente que sigue siendo montn para la clave intercambiada. Si se han intercambiado hi con h2i , se comprueba recursivamente si cumple la definicin de Williams h2i (h 2(2i ) y h 2(2i )+1). De modo similar, si se han intercambiado hi con h2i+1 , las nicas claves a comprobar recursivamente son las referidas a h 2i+1 (h 2(2i+1) y h 2(2i +1)+1.

Ver escolio para una discusin mayor.

Pag 82. Lnea 8 de 2.3.3.Dice: hasta encontrar una menor.

Debe decir: hasta encontrar una menor o igual.

Misma errata tres lneas ms abajo, donde debe decir: menores o iguales que el pivote (esto es, incluyendo al pivote) y a la derecha...

Pag 86. Lnea 5 desde el final.Dice: En el mejor de los casos el pivote queda en el centro.

Debe decir: En el mejor de los casos el pivote queda en el centro y es la mediana de cada particin.

*aadido*

Pag 89. Final primer prrafo de 'Calculo del k-simo mayor elemento'

Dice: Por generalidad se resolver el problema para k.

Debe decir: Sin perdida de generalidad se resolver el problema para k = n DIV 2

VOLVER AL NDICE...Salto de pgina...

TEMA 3

Pag 97. Programa 3.1, segunda lnea.

Dice: ...en long devuelve... Debe decir: ...en longc devuelve...

Pag 97. Programa 3.1.

No est declarada la variable w usada como argumento en los procedimientos predefinidos ReadWord y WriteWord. En los fuentes del CD, esta variable w, aparece declarada globalmente (para todos los procedimientos del mdulo) como Integer.

Despus de las dos sentencias create hacen falta sendas sentencias reset(a), reset(b)?Pag 99. Programa 3.3

Sobran las lneas:

WriteString('c=');

ListSec(c);

.../...

WriteString('Fin de ordenacin');

WriteLn;

ListSec(c);

pues se refieren al procedimiento ListSec usado para presentar los datos en los ejecutables del CD pero no es usado en los tres mdulos del texto, que slo contemplan la implementacin del algoritmo de clasificacin externa por mezcla.

Pag 101. Anlisis de la mezcla directa.

Falta aclarar en el texto que tanto la discusin como la frmula se refieren a la mezcla directa balanceada (una sola fase). Si la frmula fuese la expresin de un orden de complejidad (no lo es), tambin valdra para la mezcla directa en dos fases pues su coste (slo movimientos) es M = 2nlogn

Pag 104. Lnea 6.

Dice: Sin embargo, este razonamiento no es correcto ... nuevas mezclas.

Debera decir algo similar a: Sin embargo, este razonamiento, siendo correcto, no es el optimo debido a que en la fase de distribucin pueden aparecer directamente mezclas espontneas con el consiguiente ahorro de pases.

Creo que se ajusta bastante el calificativo de 'espontneas', pues son mezclas no predecibles que producen ordenacin sin que dependan de ningn algoritmo (excepto el de identificacin de la subsecuencia ordenada).

Pag 121. Lnea 6, debajo figura 3.13.Dice: c1(n+1) = c1(n)+ c2(n)= c1(n) + c1(n - 1) + c1(n - 2) + c1(n - 3) + c1(n - 2)

Debe decir: c1(n+1) = c1(n)+ c2(n)= c1(n) + c1(n - 1) + c1(n - 2) + c1(n - 3) + c1(n - 4)

Y a la posible errata:

c4 =1 y c i = 0 para i < 4

Si c i significa 'nmero de subsecuencias ordenadas en una cinta cualquiera en el nivel i ' (no encuentro otro posible significado), debera decir: c 1 = 1 y c i = 0 para i < 1

Pag 122. Figura 3.14.

Faltan las tres primeras filas de la tabla; necesarias para la correcta cuenta de pases.

Creo que estas filas son (usando la definicin que tiene como primeros nmeros para orden 1 precisamente 1 y 1, no 0 y 1): (ver escolio para una discusin mayor)

Nmero de cintas (N):345678

111111

111111

234567

*aadido* haba un errata en el original (no se libra de erratas ni la fe de erratas!)

Pag 129. Sexta lnea desde abajo.Dice: (Prez ( 4, Garca ( 1, ...)

Debe decir (Prez ( 1, Garca ( 2,...)

...Salto de pgina...

Pag 130. Segundo epgrafe.

Si no he entendido mal lo que aqu se dice, sera necesario cambiar la redaccin de la lnea 5:Dice: ... se clasifica el archivo de ndices. Para recuperar una llave x ...

Debe decir: ...se clasifica [inicialmente] cada bloque del fichero de datos. Para recupera una clave y...

O bien: ... se clasifican [inicialmente] los bloques de modo que no haya solapamiento de claves entre grupos. Para recuperar una clave y...

y tambin en lnea 6:

Dice: ...o igual que x, y posteriormente...

Debe decir: ...o igual que y, y posteriormente...

Tampoco es muy afortunada la figura 3.16. Un posible ejemplo alternativo con grupos de cinco registros es:

Direccin de grupoclave

direccin de registroclaveResto campos

9918

......

10087

......

10188

11003

10290

10526

10392

12041

10496

11560

10526

10087

10634

......

10735

......

10838

10940

Fichero de ndices

11003

11107

11212

11314

11417

11560

11661

11762

11866

11970

12041

Fichero de datos

Pag 133. Definicin 3.9.

No ser Densidad de llaves = nx / m ?.

Ver escolio.

Pag. 135. Figura 3.19 La suma del caso c) est mal realizada, pues en a) se han omitido los dgitos ms significativos cuando son 0 (suponiendo codificacin en 8 dgitos binarios ( 3 dgitos decimales).

068075082071063093102075

Por tanto la suma correcta para c) es:

075

201 093

360 071

280 075

+860 ------------

2015

...Salto de pgina...

Pag 136. Segunda lnea.

Interpretndola al pie de la letra, el significado de esta frase es contradictorio con la figura 3.19.

Dice: ...y sumar los dgitos coincidentes.

Debe decir: ...y sumar los dgitos de posiciones coincidentes. (O una frase similar; ver Escolio a la pgina 135)

Pag 139. Figura 3.20, pie y cabeceras columnasEn las cabeceras, figura siempre el mismo factor de carga. Es de suponer que cuanto ms a la derecha est una columna, mayor ser el factor de carga

En el pie dice ...accesos a bloques... Debe decir: ... accesos a bucles [de manejo de sobrecargas]...

VOLVER AL NDICETEMA 4

*aadido* (con la colaboracin de Rafa Pons [email protected])Pag 152. Tercer lnea desde el final.Creo conveniente cambiar toda la ltima frase pues es confusa, especialmente sobre a qu liberacin de memoria se refiere (la del nodo de punteros siempre se produce).

Una alternativa, ms larga, podra ser (ver el excolio correspondiente para una explicacin de los nombres, parcialmente incorrectos, que uso aqu: nodo de punteros y nodo de datos):

Es decir, para eliminar un nodo de la lista de punteros, lo primero que habr que hacer ser reducir el correspondiente contador del nodo de datos en una unidad, si despus de esto el contador vale cero se libera el espacio de memoria del nodo de datos y finalmente (siempre, se elimine o no el nodo de datos) se producir la liberacin de memoria correspondiente al nodo de punteros, previa modificacin de los enlaces necesarios.

Si lo que se desea es eliminar un nodo de datos, habr que recorrer todas las listas de nodos de punteros. En cada una de las que tengan una referencia al nodo de datos se producir la consabida reduccin del contador, modificacin de enlaces en la lista de punteros y la liberacin del espacio del nodo de punteros implicado. Slo en la ltima de las listas de punteros que referencian al nodo de datos se producir adems la liberacin de este espacio de memoria.

Como los que aqu llamo 'nodos de punteros' ocupan poco espacio de memoria es posible (aunque no s si se har as en la prctica) que en la eliminacin de un nodo de punteros (dejar de referenciar a un nodo de datos) no se produzca directamente la liberacin del espacio de memoria de aquel, cambiando simplemente el nodo de enlace (el que apunta al nodo de datos) a NIL. Sera entonces una rutina la que ante un evento determinado (por ejemplo, tiempo o la eliminacin de un nodo de datos) la que recorrera todas las listas de punteros para localizar enlaces a NIL y realizar el reenlace y liberacin de memoria.

Pag 178. Programa 4.14. PROCEDURE Sacar_cola.El procedimiento saca un elemento aunque la cola se haya inicializado. Una posible solucin (resaltados en gris los aadidos):

PROCEDURE Sacar_cola (VAR cola: Tipo_cola; VAR dato : Tipo_datos);

VAR

aux : Ptr_nodo;

BEGIN

IF ~Cola_vacia(cola) THEN aux := cola.frente;

dato := cola.frente^.datos;

cola.frente := cola.frente^.enlace;

IF cola.frente = NIL THEN cola.final := NIL END;

DEALLOCATE(aux,SIZE(Nodo));

END;END Sacar_cola;

Ver el escolio correspondiente.

...Salto de pgina...

Pag 181. Programa 4.16. Sealada tambin por Jess Guerreiro Real de Asua ([email protected]) Casi al final de la pgina dice:

error := error AND ((((ch1 = ')')&(ch2 = '('))) OR

(((ch1 = ']')&(ch2 = '['))) OR

(((ch1 = '}')&(ch2 = '{'))))

Debe decir:

error := ~(((ch1 = ')')&(ch2 = '(')) OR

((ch1 = ']')&(ch2 = '[')) OR

((ch1 = '}')&(ch2 = '{')))

(falta un negacin; sobran error AND y tres pares de parntesis)

Ver escolio correspondiente.

Pag 183. Programa 4.17. Ojo no introducir expresiones con [ ] o { }. El programa no los contempla y dara un resultado errneo.El ejecutable correspondiente que figura en el CD, trunca la cadena de salida.

Convierte:

la cadena infija a+b*c en la prefija *bc, en vez de la correcta +a*bcla cadena infija (b+c)*a+e en la prefija ++ae, en vez de la correcta +*+bcaeSi queda tiempo, volver sobre el fuente para buscar el fallo. Pistas: si la cadena es larga, la transformacin es correcta; parece que es un problema de presentacin, no de transformacin.

La cadena infija (((a-b)/c)+d+e)*f la convierte en la postfija ab-c/de+f*+, siendo correctas:

ab-c/d+e+f* o ab-c/de++f* dependiendo de la parentizacin que se quiera usar para las dos sumas.

Parece que el problema slo se presenta con cadenas de entrada no completamente parentizadas.

VOLVER AL NDICETEMA 5

*aadido*

Pag 195. Figura 5.2.Dice: (A(F(B(E),M),H(C(P,R),N,D)))

Debe decir: (A(F(B(E),M)),(H(C(P,R),N,D)))

Pags 197, 198. Frmulas 5.1 y 5.2.No se trata propiamente de una errata (o s?), pero para evitar confusiones el valor mximo del ndice i del sumatorio debera ser h (profundidad) en vez de n (respectivamente m) que origina confusin con el denominador de mismo nombre pero diferente significado (total nodos).

*aadido*

Pag 198. Propiedad 5.2 sealada por Antonio Linde ([email protected])

Dice: Ng = (h-1i=0 g i

Debe decir: Ng = (hi=0 g i De esta errata se sigue la de la siguiente pgina donde

dice: N2 = (h-1i=0 2i = 2h 1

debe decir: N2 = (hi=0 2i = 2h+1 1

Se comprueba fcilmente la errata por ejemplo con la figura 5.4, que siendo de profundidad h=3, el nmero mximo de nodos es 20 + 21+ 22 + 23 = 1 + 2 + 4 + 8 = 15 = 23+1 1

*aadido*

Pag 200. Linea antes de 5.2.1 sealada por Antonio Linde ([email protected])

Dice: Por tanto, para n niveles se...

Debe decir: Por tanto, para n nodos se...

*aadido* en el original deca pag 201

Pag 204. Figura 5.7.

Los nodos 69 y 23 estn intercambiados. Sealada tambin por Jess Guerreiro Real de Asua y Jos Abelardo ([email protected])El ejecutable del CD demos\arb_perf_bal.exe (que por el nombre debera? dibujar este rbol), construye el mismo que demos\arb_perf_bal_r.exe programa 5.1)

Pag 203. Programa.En el fuente correspondiente del CD (tema5\modula\fuentes\arboles.mod), al final del procedimiento Perfec_balanceado dice:

BEGIN

Reset(f);

WHILE ~f.eof DO

ReadWord(f,w);

Insertar_Arbol_perf(w,k);

END;

Close(f);

END Perfec_balanceado;Debe decir:

BEGIN

Reset(f);

ReadWord(f,w); WHILE ~f.eof DO

Insertar_Arbol_perf(w,k);

ReadWord(f,w); END;

Close(f);

END Perfec_balanceado;De lo contrario, no se puede evaluar la proteccin del WHILE (en el fuente del libro, viene bien)

Pag 210. Penltima lnea del penltimo prrafo.Dice: para lo cual habr que apuntarlo previamente con un puntero auxiliar.

Debera decir: para lo cual, por respeto a la generalidad del programa 5.5, habr que apuntarlo previamente con un puntero auxiliar

Pag 214. Primera lnea despus del programa.Dice: Dado que la bsqueda es dirigida...

Debe decir: Dado que la insercin es dirigida...

Pag 215. Mitad de la pgina, tercera secuencia.El rbol no es perfectamente balanceado, pues la rama izquierda del nodo 10 tiene 3 nodos y la derecha ninguno (difieren en ms de uno).

Si en la secuencia dada se intercambian, por ejemplo, el 9 y el 10, pasa a tener un rbol de bsqueda perfectamente balanceado: 16, 12, 32, 9, 22, 14, 69, 4, 13, 18, 42, 10, 15, 23, 99, 2, 17.

En el escolio correspondiente, los rboles de ambas secuencias.

Pag 242. Figura 5.28. Revisarlo por si las moscas.

El nodo 16 es hijo 'menor que' de 17. No hijo 'mayor que pero no doble' de 14.

En cualquiera caso, el 16 se inserta en el rbol antes que el 14, por lo que si el rbol fuera cierto, 16 sera algo as como hijo putativo transtemporal (a la salud de los cronogatos marcianos de Asimov, que hacan la digestin antes de comer).

VOLVER AL NDICE....Salto de pgina....

ESCOLIOS

tema 1

VOLVER AL NDICENota general a todo el tema.A pesar de la relativa facilidad de este tema, creo muy conveniente que tras el estudio de los temas 2 al 5, una vez usados exhaustivamente todos los conceptos que aqu se describen, se vuelva a leer ste primero con detenimiento. Nos podemos llevar alguna pequea sorpresa cuando de repente se haga la luz.

A partir del tema 4 se usan intensivamente punteros y listas enlazadas, por tanto no est de ms practicar con los fragmentos de cdigo que se ven en este tema, con un cuidado muy especial en no confundir operaciones con punteros y operaciones con las variables referenciadas y en no dejar nodos desreferenciados.

Pag 9. Penltima lnea del primer prrafo de 1.2.2.

Para comprobar que realmente son TDA, basta intentar una divisin real con enteros.

Pag 9. Definiciones 1.8 y 1.9.

Los calificativos 'cardinal' y 'ordinal' pueden originar malentendidos, especialmente el segundos (no confundir tipo ordenable y tipo ordinal). Han de entenderse tal como se definen aqu.

Dado el intervalo cerrado de enteros [-1,2] se puede fcilmente establecer un orden segn la relacin menor que (o mayor que): -1 < 0 < 1 < 2. Tambin fcilmente se puede establecer su cardinalidad y su 'ordinabilidad'. Estamos seguros que en la lista ordenada anterior estn los cuatro enteros comprendidos dentro del intervalo cerrado [-1,2]. Pero si este mismo intervalo cerrado es de reales la cosa cambia. No se puede establecer ninguna 'ordinabilidad': podremos escribir todos los reales que nos de la gana comprendidos entre -1 y 2 y colocarlos de manera ordenada segn la misma relacin de orden < > que en los enteros, pero en ningn momento podemos decir cual es la cardinalidad (finita) de dicho conjunto ordenado ya que siempre nos quedarn reales por incluir. El conjunto de los reales es 'ordenable', pero no es 'ordinable'

Dicho de otra manera:

Tipo cardinal: aquel en el que el conjunto de valores (atmicos) es ordenable.

Tipo ordinal: aquel en el es posible establecer una aplicacin biyectiva entre los elementos del conjunto y el conjunto de los nmeros ordinales (primero, segundo...). Desde luego esta definicin no se puede aplicar a los reales.

Y de una tercera manera: tipo ordinal ser aquel tipo cardinal en el que se pueda establecer la cardinalidad del conjunto de los valores que lo forman.

Ojo que esta clasificacin slo sirve para TDA con valores atmicos. Por ejemplo para pares ordenados de enteros (que seran registros, tipo compuesto) no es vlida.

Ms de lo mismo, pero ms claro y riguroso en el siguiente escolio recibido posteriormente a la redaccin de ste.

*aadido*

Pag 9. Principio del ltimo prrafo. Por Fran J. Carmona ([email protected])

Dice : (...) los nmeros reales no forman un conjunto ordenado al no ser numerable.

Debe decir: (...) los nmeros reales no forman un conjunto bien ordenado (con un orden bien fundado) al no ser numerable.

o bien: (...) los nmeros reales no forman un conjunto ordinal al no ser numerable.

Todo esto para que sea consistente con las afirmaciones anteriores y posteriores sobre conjuntos ordenados y ordinales.

Primero fijemos los conceptos y tipos de orden (tomado de Fernndez Via J.A., Anlisis Matemtico I, Tecnos): (ved la R como un menor o igual)

"0.2.2 Una relacin binaria R en un conjunto X se dice que es un preorden si posee las propiedades:

(1) xRx, cualquiera que sea x en X (Reflexiva)

(2) Si xRy e yRz, entonces xRz (transitiva)

cuando adems se tenga la propiedad:

(3) Si xRy e yRx, entonces x=y, la relacin R se dice que es un orden

Las condiciones de esta definicin en nada obligan a que dos elementos tomados arbitrariamente en X estn relacionados.

Cuando una relacin de preorden o de orden tenga tambin la propiedad:

(4) Cualesquiera que sean x,y en X, o bien es xRy, o bien es yRx,

entonces se dice que el preorden o el orden en cuestin es total."

De mis recuerdos:

Si en un orden o preorden tenemos una de las dos propiedades siguientes, que son equivalentes:

(5) Todo subconjunto no vaco A de X tiene un primer elemento que es menor o igual que todos los elementos de A y que pertenece a A

(5') Todo elemento tiene un nico predecesor (en el sentido del libro de EDyA)

Entonces se dice que es un buen orden o un buen preorden. En prog2 le llaman preorden (u orden) bien fundado, y aqu lo llaman ordinal.

Una vez que se define la relacin binaria y se analizan sus propiedades sta, se sublima por economa de lenguaje y no se hace referencia a ella, el conjunto hereda el nombre directamente del tipo de relacin que sea, as un conjunto totalmente ordenado es el que tiene una relacin de orden total (Todos los conjuntos de nmeros N, Z, Q y R tienen un orden total (con las relaciones usuales), salvo los complejos donde no se puede extender el orden usual en los otros conjuntos).

El conjunto de las fracciones, Q, es numerable y no es ordinal con el orden usual, vale el ejemplo del libro, pues los nmeros que usan son racionales.

Su frase (la del libro, objeto de este escolio) da a entender en realidad 'no numerable' implica 'no ordinal', sin

embargo (es un problema abierto que yo sepa) se cree que debe haber un orden (distinto del usual claro), en el cual el conjunto de los reales sea ordinal.

Para evitar posibles errores de interpretacin sera ms correcto si adems en la Definicin 1.8 se sustituyera 'el conjunto de los valores est ordenado' por 'el conjunto est ordenado'

Pag 10. Definicin 1.11.

Arreglo: en otros textos (Programacin I y II) se les llama array, vector o formacin. El Programacin I, el TDA estructurado 'formacin' incluye a los arrays propiamente dichos y a los strings o ristras (array de caracteres); estos ltimos al ser dinmicos (su tamao no est predefinido, vara segn se aadan o eliminen elementos) no se incluyen en este libro en esta definicin de arreglo.

Pag 10. ltimo prrafo.

Tambin se puede realizar un anidamiento de en un tipo estructurado dentro de un arreglo; as el ejemplo:

TYPE

TipoMes = (Enero, Febrero,...,Diciembre);

TipoFecha = RECORD

dia:[1..31]

mes: TipoMes

ano: INTEGER;

END;

TipoNombre = ARRAY [0..15] OF CHAR;

TipoCumple = RECORD

nombre: TipoNombre

fecha: TipoFecha;

END;

TipoAgenda = ARRAY [1..100] OF TipoCumple;

Donde cada posicin del arreglo contendra un registro de dos campos, el primero un arreglo con nombres y el segundo un registro que contiene una fecha.

Pag 11. Definicin 1.14.

Completar la frase 'es una coleccin homognea y dinmica de datos'

Justamente es el carcter dinmico lo que diferencia principalmente los arreglos de las listas. Tal como aparece la definicin en el libro puede parecer vlida para un arreglo unidimensional, pero no es as. En el arreglo lo que identifica a un elemento es su posicin dentro de aqul; en la secuencia se identifica por los elementos que le preceden o siguen.

El tipo estndar STRING de Modula 2 ha de considerarse como un arreglo y no como una lista, a pesar de tener un tamao aparentemente variable. Pero, por lo que recuerdo, las operaciones definidas sobre l son tpicamente estticas. No conozco ninguna que permita, por ejemplo, una insercin.

Un detalle sumamente importante para todos los TDA dinmicos (listas, colas , rboles) , y que nunca se debe olvidar, es que el carcter dinmico lo determinamos por la propia definicin del TDA y los operadores claramente dinmicos (insertar por el medio, suprimir...) asociados a l, nunca por la implementacin que se realice del TDA.

Se vern posteriormente varios ejemplos; uno muy tpico es la pila, que es un TDA dinmico pero que se puede implementar muy fcilmente sobre un arreglo (pag 157) sin perder la pila por ello su carcter dinmico.

Pag 17. Definicin 1.15.

En ningn caso las operaciones realizadas sobre las variables referenciadas por un puntero se pueden considerar como operaciones sobre el tipo puntero.

Pag 18. Penltima lnea.El TDA puntero, tambin es tipo ordinal segn la definicin 1.9. Es atmico, ordenable y triste sera si no fuera ordinal.

Pag 20. Final.

Aqu es donde, al menos en mi centro asociado, nos montbamos el cirio padre en Programacin 1, donde se presentaba primero la estructura secuencia y despus los punteros, por lo que entendamos los punteros como un tipo rarsimo que hace una referencia circular. Nada de eso. Un puntero es trivial, tal y como se vio por ejemplo en la figura 1.3, con unas declaraciones de tipo y variables absolutamente triviales. Por ninguna parte aparecen referencias circulares ni nada que se le parezca.

Visto as, una declaracin de tipo Nodo, como en el ejemplo de esta pgina no es ms rara que la siguiente:

TYPE TipoPuntero = Integer;

TipoNodo = RECORD

datos : TipoDatos

enlace : TipoPuntero;

END;Aunque no nos sirve para crear una lista enlazada es tan correcta y simple como la del tipo Nodo del libro o la de unas lneas ms abajo. La nica particularidad de la declaracin de tipo puntero es que si ste apuntar a un tipo nodo, el compilador permite hacer la declaracin sobre un tipo todava no definido; siendo el nico caso en que esto puede ocurrir.

Para verlo ms claro: tenemos la siguiente declaracin de tipos (como la anterior pero ya con TipoNodo) y de variables:

TYPE TipoPuntero = POINTER TO TipoNodo;

TipoNodo = RECORD

datos : TipoDatos

enlace : TipoNodo;

END;VAR principio, final, ultimo_visitado: TipoPuntero;

nuevo_nodo: TipoNodo;

y la siguiente lista:

p

u

f

principioultimo visitadofinal

nuevo_nodo

Las tres primeras variables, es trivial que no son ms que una direccin de memoria que contiene la direccin donde se encuentra algn nodo particular de una lista (primero, ltimo, ltimo visitado). Queremos ahora insertar un nuevo_nodo entre el ltimo visitado y su siguiente. Por mucho que lo intentemos, no hay manera de conseguir que la lista quede conformada por las flechas negras y grises (sin la azul) sin dejar en algn momento un nodo desreferenciado. Es necesario usar un puntero auxiliar que apunte a alguno de estos nodos desreferenciados. Pero, ya que tenemos que hacerlo, cambiemos un poco la estrategia y ahorremos la declaracin de variable TipoNodo. Ahora todas las operaciones sobre el nuevo nodo se declararn siempre a travs de un puntero. En las pginas que siguen, bastantes ejemplos de esta mecnica.

Pag 21. Segundo prrafo.

No veo que se gana en claridad. Para eso, habra resultado ms sencillo llamar directamente al tipo puntero Tlista en vez de Ptr_Nodo (por supuesto modificando tambin el nombre del tipo del campo enlace)

*aadido* con la colaboracin de Albert R. Garrido [email protected] no aporta para la lectura de los mdulos de definicin e implementacin del TDA lista enlazada, pero ofrece una importante ventaja. Supongamos que tenenemos escrito un programa determinado que usa una lista enlazada (mediante importacin del mdulo adecuado). Todas sus variables del tipo lista enlazada se declarn como nombre_variable:tlista. Supongamos ahora que tenemos otros mdulos de definicin e implementacin para un TDA lista doblemente enlazada (ya se ver ms adelante en que consiste), que por supuesto, su declaracin de tipo bsico no ser como en este caso TYPE Ptr_Nodo POINTER TO Nodo, si no uno similar a TYPE tipo_doble POINTER TO Nododoble. Si ahora en nuestro programa queremos usar este nuevo TDA, deberemos editarlo (y despus volver a compilar) para sustituir todas las apariciones de Tlista por tipo_doble a la vez que se importa un mdulo diferente. Pero si en este mdulo se realiz la declaracin de tipo Tlista=tipo_doble, en nuestro programa no tenemos que hacer otra cosa que importar el mdulo adecuado, pues todas las variables siguen siendo de tipo correcto (a pesar de haber cambiado!). En el tema cuatro se usa un nombre de tipo todava ms genrico: lista.

Pag 23. Programa 1.1.

Al menos en mi libro las cifras de la izquierda (que se corresponden con los pasos de la figura 1.12) estn decaladas lnea y media. Deberan estar a la altura de las cuatro sentencias comprendidas entre Begin y End.

En este ejemplo se ve que se realizan dos operaciones sobre TDA puntero (sentencias 3 y 4) y una sobre el TDA Tipo_dato.

Pag 25. Programa 1.2.Aparentemente en este procedimiento Insertar_final, el parmetro lista se podra recibir por valor y no, tal como figura, por referencia (VAR) pues en principio dicho puntero, por apuntar a la cabeza, no se va a modificar al insertar por el final. Pero si la lista est vaca, se entrar en la rama THEN del IF invocndose al procedimiento Insertar_cabeza que s necesita modificar el puntero. Por tanto, Insertar_final s necesita recibir lista por referencia para poder devolver al procedimiento invocante original el nuevo valor del parmetro en el caso de que la lista est originalmente vaca.

Pag 26 y 27. Programas 1.3 y 1.4.

Tal como se indica en las Conclusiones del tema, en ambos programas, 'no se ha considerado la posibilidad de que la lista est vaca (...). [En una implementacin para un caso real] es imprescindible, que previa a la eliminacin del nodo, el programa principal llame a una funcin que indique si la lista est vaca y obre en consecuencia (...)'.VOLVER AL NDICE...Salto de pgina....

ESCOLIOS tema 2

VOLVER AL NDICEPag 46. ltimo prrafo.

A lo largo del texto se usan 'clave' y 'llave' como sinnimos.

Pag 50. Programa 2.1.

VAR i,j:INTEGER

BEGIN

FOR i:=2 TO n DO

a[0]:=a[i]; (*garantiza la salida del while*)

j:=i;

WHILE a[0]a[j+1] THEN

aux:=a[j+1];

a[j+1]:=a[j];

a[j]:=aux;

k:=j

END

END; (*del FOR*)

R:=k-1;

IF R>=1 THEN

FOR j:=R TO L BY -1 DO

IF a[j]>a[j+1] THEN

aux:= a[j+1];

a[j+1]:=a[j];

a[j]:=aux;

k:=j;

END;

END; (*del FOR*)

L:=k+1;

END;

UNTIL L>R;

END;

De esta manera, al terminar la primera pasada, por evaluarse a falso el IF se pasa directamente a la sentencia Until, que se evala a cierto terminndose la ejecucin.

Otra solucin menos elegante sera editar el mdulo de definicin (en el CD tema2\modula\clfarray.def, del que copio y pego 5 lneas)

DEFINITION MODULE clfarray;

TYPE

Tipoarray1=ARRAY[0..n] OF INTEGER;

Tipoarray2=ARRAY[1..n] OF INTEGER;

PROCEDURE vibracion (VAR a:Tipoarray2);

y sustituir 2 por 1

Pag 68. Lnea 5 (no programa).Si el coste mnimo de las comparaciones es n-1, se est suponiendo que no se entra en el segundo FOR. No ando pues tan descarriado.

Pag 70. Figura 2.9

En los diagramas de la derecha, crculos y flechas tienen el mismo significado que en insercin directa (figura 2.2 pag 49). El circulo indica la clave que se inserta y las flechas los desplazamientos

Pag 71. Segundo prrafo.Para saber a qu grupo pertenece la llave de posicin i en la clasificacin j, basta hacer iMODj, el resultado ser el grupo. De ah que 'el nmero de grupos ser siempre el mismo que el incremento escogido'.

Pag 72. Programa 2.6En el programa se usa 'nmero de ordenacin' con el mismo significado que 'nmero de clasificacin'.

No es ms que una derivacin a partir del de insercin directa. Partiendo de l y modificndolo poco a poco llegaremos al programa buscado.

Ahora bien, mucho cuidado, la mecnica del programa (el algoritmo que implementa) es distinta a la explicada al principio de la pag 71 y en la figura 2.9. All, dentro de cada clasificacin se recorre y ordena primero el grupo 1, despus el 2 y as sucesivamente. El algoritmo que sigue el programa 2.6 implica, para cada clasificacin, un recorrido secuencial del arreglo, sin distinguir grupos. Sern los centinelas los que distingan el grupo. En los comentarios por lneas del programa ms abajo, un poco ms claro (?) el procedimiento.

Programa de insercin directa original:

VAR i,j:INTEGER

BEGIN

FOR i:=2 TO n DO

a[0]:=a[i];

j:=i;

WHILE a[0]> nlognnlogn< nlogn

Mezcla balanceada mltiple

nlognn logN n Con N nmero de cintas destino

Mezcla Polifsica????????????

Coste recuperacin de una clave

Hash con bsqueda cuadrtica o con rehashingln(1-() / (

Hash con encadenamientos1 + (( / 2)

VOLVER AL NDICE....Salto de pgina....ESCOLIOS tema 4

VOLVER AL NDICE*aadido* (con la colaboracin de Rafa Pons [email protected])Pag 152. Tercer lnea desde el final.Para evitar confusiones en este escolio y el siguiente me permitir la licencia de usar los nombres de 'listas de punteros' para las formadas por nodos que slo contienen punteros (a los que llamar 'nodos de punteros') y 'lista de datos' a la formada por 'nodos de datos'. Cuando en el libro hablan de 'lista' se refieren a la 'lista de datos' (aunque ella sola no constituye en absoluto una lista enlazada a pesar de ser la 'lista de verdad')

Creo conveniente cambiar toda la ltima frase pues es confusa, especialmente sobre a qu liberacin de memoria se refiere (la del nodo de punteros siempre se produce). Una alternativa puede ser por ejemplo:

Es decir, para eliminar un nodo de la lista de punteros, lo primero que habr que hacer ser reducir el correspondiente contador del nodo de datos en una unidad, si despus de esto el contador vale cero se libera el espacio de memoria del nodo de datos y finalmente (siempre, se elimine o no el nodo de datos) se producir la liberacin de memoria correspondiente al nodo de punteros, previa modificacin de los enlaces necesarios.

Si lo que se desea es eliminar un nodo de datos (en el ejemplo del fichero de libros de la pgina 152 sera elminar un libro), habr que recorrer todas las listas de nodos de punteros. En cada una de las que tengan una referencia al nodo de datos se producir la consabida reduccin del contador, modificacin de enlaces en la lista de punteros y la liberacin del espacio del nodo de punteros implicado. Slo en la ltima de las listas de punteros que referencian al nodo de datos se producir adems la liberacin de este espacio de memoria.

Como los que aqu llamo 'nodos de punteros' ocupan poco espacio de memoria es posible (aunque no s si har as en la prctica) que en la eliminacin de un nodo de punteros (dejar de referenciar a un nodo de datos) no se produzca directamente la liberacin del espacio de memoria de aquel, cambiando simplemente el nodo de enlace (el que apunta al nodo de datos) a NIL. Sera entonces una rutina la que ante un evento determinado (por ejemplo, tiempo o la eliminacin de un nodo de datos) la que recorrera todas las listas de punteros para localizar enlaces a NIL y realizar el reenlace y liberacin de memoria.

Veamos una posible implementacin de los nodos (que no es en absoluto una implementacin del TDA)

Nodos de datos:

TNodoDatos = RECORD

datos : TipoDatos;

contador : CARDINAL

END;

(*como en todo el libro, TipoDatos no es ms que una simplificacin que esconde posibles campos mltiples, cada uno del tipo que sea*)

Nodos de punteros:

TPunteroNodoDatos = POINTER TO TNodoDatos

TNodoApuntador = POINTER TO NodoApuntador;

NodoApuntador = RECORD

ant : TNodoApuntador;

puntero : TPunteroNodoDatos;

sig : TNodoApuntador

END;

Puede que estas declaraciones de tipo no sean estrictamente correctas (desde luego exceden en complejidad a lo que -por ahora- estamos acostumbrados), pero s me importa destacar un par de cosas. Los variables que se declaren (y creen dinmicamente) del tipo TNodoDatos no se pueden considerar nodos pues carecen de tipo alguno de enlace. Los nodos 'verdaderos' de tipo TNodoApuntador slo contienen los enlaces a anterior y siguiente (por tanto del mismo tipo TNodoApuntador) y un apuntador (llamado puntero) a un elemento de tipo TNodoDatos, careciendo de toda informacin que no sean direcciones de memoria. Es cierto que si tenemos, como en la figura 4.9, varias listas cuyos nodos apuntan a los mismos datos, en alguna parte ha de haber informacin sobre qu criterio de ordenacin sigue cada lista. Esto no es, creo, ningn inconveniente; bastara por ejemplo la siguiente declaracin de tipo y variables:

Tlista = RECORD

criterio : ARRAY OF CHAR (*o cualquier informacin til*)

primero,ultimo: TNodoApuntador; END

VAR

lista, lis1, lis2, lis3 : Tlista.

Otra consideracin de suma importancia es que el acceso o cualquier operacin sobre los elementos de TNodoDatos slo se puede realizar a travs de un puntero (el del campo puntero de un nodo TNodoApuntador)

Veamos ahora como sera la eliminacin de un nodo puntero (la eliminacin de un nodo dato se implementara como un procedimiento que tendra como ncleo principal el siguiente procedimiento).

PROCEDURE EliminaReferencia(VAR Nodo:TNodoApuntador);

BEGIN

1 Nodo.puntero^.contador:=Nodo.puntero^.contador-1

2 IF Nodo.puntero^.Contador=0 THEN

3 DEALLOCATE(Nodo.puntero^,SIZE(TNodoDatos)); END;

4 Nodo.Puntero:=NIL; (*Referencia Eliminada*)

5 EliminaNodo(Nodo)

END EliminaReferencia;

Comentmoslo por lneas.

Cabecera: no hace falta recibir como parmetro de qu lista se trata, al procedimiento poco le importa, pero actuar sobre la correcta porque as lo deciden los punteros de los campos enlace de Nodo. Surge aqu una duda importante ha de pasarse por referencia el nodo de datos apuntado por Nodo?, es posible que dentro del procedimiento se libere su espacio de memoria. De todos modos, creo que no es necesario.

1) No plantea problemas.

2) Slo si el contador es cero, el espacio de memoria ocupado por el elemento (nodo de datos) se puede y

debe devolver (3) al S.O como disponible ya que al no quedar ninguna lista que lo referencie no se puede acceder a l y lo nico que hace es consumir memoria inutilmente.

(4) esta lnea sobra por completo, la pongo slo para resaltar que la lista a la que pertenece el nodo ha dejado de referenciar al elemento. Por supuesto, si el contador es mayor que 0 habr otras listas que lo sigan referenciando. Si encambio se sigue la estrategia indicada al principio de no liberar inmediatamente los nodos de punteros, esta lnea s existira.

(5) Se invoca a un procedimiento que realice la supresin fsica del nodo de punteros que, entre otras cosas tendr que realizar el correcto reenlace de los nodos anterior y siguiente. Si se sigue la estrategia de no liberar nodos de punteros, esta lnea no existira.

En cualquiere caso, al implementar el TDA ' lista multireferenciada' hay que tener especial cuidado en no introducir inconsistencias, como por ejemplo crear un nuevo nodo de datos (elemento de la lista en la terminologa del libro) que no est referenciado por ningn nodo de punteros, o realizar una modificacin en una lista de punteros sin actualizar el correspondiente campo contador.*aadido* (contiene algunas modificaciones sobre la primera versin)

Pag 153. Figura 4.9Con las listas multiferenciadas, las operaciones permitidas sobre el TDA pueden ser ms que en el caso de las listas ordenadas normales, pues aqu estn ms separadas las operaciones sobre la lista de datos y las operaciones sobre las listas de punteros.

Por ejemplo, si la ltima lista en crearse fue Lis3, no hubo que reservar memoria para el nodo de datos, slo fue necesario para el nodo de punteros (dos de enlace y uno al dato). Tambin se puede permitir, por ejemplo, una operacin que consista en la eliminacin fsica (liberacin de memoria) de toda una lista de punteros previa comprobacin de que ningn contador queda a ceros. Esta operacin sera til en el caso de que la lista de punteros a suprimir sea una de consulta temporal similar a la mencionada en la pgina 152, primer prrafo.

Si al contrario que en la figura, se exige que exista una Lista maestra principal, el manejo de sta ser similar a las listas normales, con la excepcin principal que habra que hacer doble reserva de memoria; una para datos y otra para los punteros. Para las otras listas dependientes se podran definir operaciones slo sobre los punteros, y as la liberacin de memoria de un dato se hara nicamente desde la principal, siempre y cuando el contador de referencias fuese igual a uno.

Incluso se podra hacer de tal modo que la lista maestra fuera una lista enlazada normal (eso s, cada nodo tendra adems de los campos datos y enlaces un campo contador). Esta solucin hara ms difcil la posibilidad de inconsistencias como las mencionadas en el escolio anterior.

Pag 157. Programa.No es necesaria la implementacin usando un registro; se puede usar un array y un entero directamente, pero esto impedira la elegancia de la implementacin de las operaciones bsicas Meter_pila y Sacar_pila de la siguiente pgina:

pila.datos[pila.cima]:=nuevo_dato Pag 159. Segundo prrafo.

La figura 4.12.b en efecto tiene un elemento, que es H, no F, pues partiendo de 1.12.a se increment pila.cima y despus se introdujo el nuevo_dato H

Pag 161. Primer programa.Puede parecer a primera vista que es innecesario el puntero auxiliar, pero es imprescindible para poder realizar la liberacin de memoria.

Pag 161. Penltimo prrafo.Recordatorio de Modula 2. Las funciones usan desafortunadamente la misma palabra clave PROCEDURE que los procedimientos, pero se diferencian en que en la cabecera ha de figurar el tipo del dato que devuelve y en el cuerpo la palabra clave RETURN en la lnea que declara dicho valor a devolver.

Pag 164. Figura 4.14ltima lnea de la figura. (d=8) d es el segundo parmetro que se paso a sup_cola en la lnea de arriba.

Pag 175. Principio de la pgina.TYPE Ptr_nodo = POINTER TO Nodocola;

Nodocola = RECORD

datos : Tipo_datos;

enlace : Ptr_nodo;

END;

Tipo_cola= RECORD

frente,final: Ptr_nodo;

END;

Lo que en esta declaracin de tipos se denomina Tipo_cola a lo largo de todo el texto que sigue se denomina cola a secas, pues en los procedimientos que implementan las diferentes operaciones, en sus respectivas listas de parmetros se usa la variable colas (unas veces por referencia y otras por valor) de tipo Tipo_colas.

Como todas las operaciones se harn sobre el frente o el final de la cola, el campo enlace nunca se usar directamente de la forma nodo.enlace^ (excepto en punteros auxiliares, siendo nodo de tipo Nodocola).

Pag 175. Segundo prrafo.

Dicho de otra manera:

Frente apunta al primer elemento de la cola, al ms 'viejo', el que lleva ms tiempo en cola; final apunta al ltimo, que ser el ms 'joven'; y entre nodos, los enlaces van de viejo a joven. Por tanto, la estrategia que se apunta en la tercera lnea (suprimir por el final), aparte de no poder implementarse de manera econmica, es contraria al concepto FIFO!.

Cae de cajn que no queda ms remedio que meter (jvenes) por el final y sacar (viejos) por el frente.

Pag 175. Tercer prrafo.Cuidado! final (o ms correctamente cola.final, FI en las figuras 4.23 y ss) es el puntero que apunta al ltimo nodo (al ms joven) y por tanto slo estar a NIL si la cola est vaca o se inicializa a cero (se limpia). En cambio, el campo enlace de este mismo ltimo nodo siempre estar a NIL (siempre: cola.final^.enlace=NIL).

*aadido*. En la primera edicin, en la tercera lnea, donde ahora dice cola.final^.datos, antes deca cola.final^.enlace.

Pag 178. Programa 4.14. PROCEDURE Sacar_cola.Hay un error en el procedimiento. Veamos:

Supongamos que tenemos una cola como la indicada en la figura 4.25 con 5 nodos y en la que cola.frente^.datos=3 y cola.final^.datos=15.

Ahora supongamos que se realizan las siguientes acciones.

Limpiamos la cola (inicializarla, ponerla a cero), ejecutando el procedimiento:

PROCEDURE Inicia_cola (VAR cola: Tipo_cola);

BEGIN

cola.final := NIL;

END Inicia_cola;

Nos queda el diagrama de la cola idntico al de la figura 4.25, con la salvedad que ahora en el puntero cola.final pintamos una X y borramos la flecha que va al ltimo nodo.

No nos damos cuenta que la cola est 'vaca' y llamamos al procedimiento:

PROCEDURE Sacar_cola (VAR cola: Tipo_cola; VAR dato : Tipo_datos);

VAR

aux : Ptr_nodo;

BEGIN

aux := cola.frente;

dato := cola.frente^.datos;

cola.frente := cola.frente^.enlace;

IF cola.frente = NIL THEN cola.final := NIL END;

DEALLOCATE(aux,SIZE(Nodo));

END Sacar_cola;

que se ejecuta. Se obtiene el dato del nodo ms viejo de la cola a pesar de haberla inicializado, pues no realiza comprobacin alguna del estado del centinela que hemos establecido para cola vaca.

Una posible solucin:

BEGIN

IF ~Cola_vacia(cola) THEN aux := cola.frente;

dato := cola.frente^.datos;

cola.frente := cola.frente^.enlace;

IF cola.frente = NIL THEN cola.final := NIL END;

DEALLOCATE(aux,SIZE(Nodo));

END;END Sacar_cola;

...Salto de pgina....Pag 181. Programa 4.16 Desarrollo a partir de una errata descubierta por Jess Guerreiro de Asua.

El programa contiene un error que hace que funcione mal:

MODULE parentizar;

(*Comprueba si una expresin esta bien parentizada*)

FROM InOut IMPORT WriteString,Read,ReadInt, WriteLn,Write,WriteInt;

FROM pilarray IMPORT Tipo_pila, Inicia_pila, Meter_pila,Sacar_pila,Pila_vacia;

CONST

long = 30;

TYPE

Tipo_conj = SET OF CHAR;

VAR

abierto : Tipo_pila;

ch1,ch2 : CHAR;

error : BOOLEAN;

abre,cierra : Tipo_conj;

BEGIN

abre := Tipo_conj{'(','[','{'};

cierra := Tipo_conj{')',']','}'};

Inicia_pila(abierto);

error := FALSE;

WriteString('Introduzca cadena con un punto para terminar:');

WriteLn;

Read(ch1);

WHILE (ch1#'.')&(NOT error) DO Mientras no llegues al final de la cadena y no hay error:

Write(ch1);

(*Tratamiento de cada carcter ledo*)

IF ch1 IN abre THEN Si es un parntesis abierto, mtelo en la pila.

Meter_pila (abierto,ch1);

ELSIF ch1 IN cierra THEN Si no fue abierto, y es cerrado (dems caracteres, saltan los IF):

error := Pila_vacia(abierto); Se pondr a TRUE si no hay abiertos para el cerrado que ests evaluando.

IF NOT error THEN pero si el falso que la pila est vaca:

Sacar_pila (abierto,ch2); saca el abierto del tope y ponlo en ch2.

Antes de seguir, remarcar que para llegar a la siguiente sentencia, no hubo previamente descompensacin de parntesis y, sobre todo, que error = FALSE.

Los parntesis destacados en gris son los caracteres de comparacin, no forman parte de la parentizacin de la expresin booleana; los destacados en rojo sobran y los azules encierran toda la segunda proposicin del AND.

error := error AND ((((ch1 = ')')&(ch2 = '('))) OR

(((ch1 = ']')&(ch2 = '['))) OR

(((ch1 = '}')&(ch2 = '{'))))En esta sentencia, lo nico que queremos saber es si el abierto sacado (ch2) es del mismo tipo que el cerrado (ch1) con el que entramos en el ltimo IF. Por tanto, sobra lo destacado en negrilla que lo nico que consigue es forzar un FALSE, pues error := FALSE AND (....).

De esta manera, si no hay descompensacin de parntesis, finalmente se entrar siempre en la rama ELSE del IF de 5 lneas ms abajo, contestando Bien parentizado, independientemente de si lo est o no.

Adems, es necesario incluir una negacin antes del primer parntesis azul para que error tome TRUE slo en el supuesto que exista un mal emparejamiento (en esta situacin todo lo comprendido entre parntesis azules sera FALSE), situacin en la que no se volvera a entrar en el While.

END

END;

Read(ch1);

END;

IF NOT Pila_vacia(abierto)OR error THEN Si al terminar la cadena la pila no est vaca (no hubo suficientes cerrados para los abiertos de la pila) o si se produjo algn error:

WriteString('Mal parentizado')

ELSE

WriteString('Bien parentizado')

END;

END parentizar.

Resumiendo, el programa, tal como figura en el libro, detecta mala parentizacin slo si sta est descompensada. En caso contrario no es capaz de discernir si los emparejamientos son correctos y dir siempre que est bien.

Pag 182. Segundo y tercer prrafo.

Con los ejemplos que trae el libro, es bastante difcil obtener una generalizacin para realizar la transformacin de manera manual y cmoda. En la primera versin de este documento iba un procedimiento bastante complejo, que sin embargo era relativamente fcil de implementar iterativamente. Con posterioridad, al llegar a la pgina 206 aparece un mtodo grfico, cmodo y recursivo basado en rboles. Para su implementacin vese all; pero para una transformacin rpida y manual, el siguiente algoritmo tambin recursivo:

Algoritmo recursivo_lpiz_y_papel.

Supongamos que tenemos un procedimiento del mismo nombre al que se le pasa como argumento una cadena, el procedimiento busca en la cadena el operador ms prevalente y escribe el operador y los operandos que lo flanquean en forma prefija (o postfiia) y si alguno (o ambos) de estos operandos son a su vez cadenas, se vuelve a llamar al procedimiento (una o dos veces) con la subcadena correspondiente:

Un ejemplo grfico de paso a pre y post con una nica llamada en cada paso. Destacado en gris, el argumento que se pasa en la siguiente invocacin al procedimiento. Si se est haciendo a mano, no es necesario transcribir todo, basta dejar el espacio suficiente.

A prefija:

a postfija:a+({b-[(c*d)/e]}^f)

a+({b-[(c*d)/e]}^f)+a{b-[(c*d)/e]}^f

a({b-[(c*d)/e]}^f)+

+a^{b-[(c*d)/e]}f

a{b-[(c*d)/e]}f^+

+a^-b[(c*d)/e]f

ab[(c*d)/e]-f^+

+a^-b/(c*d)ef

ab(c*d)e/-f^+

+a^-b/*cdef

abcd*e/-f^+

Atencin que en postfija los operadores se insertan delante de los ya escritos.

Un ejemplo de paso a pre y post con ms de una llamada en cada paso (puede ser til dibujar a mano el castillo de quebrados).

A prefija:

a postfija:[(a+b)/(c+d)]/{(e*f)/[(g+h)*(i-j)]}[(a+b)/(c+d)]/{(e*f)/[(g+h)*(i-j)]}/(a+b)/(c+d) (e*f)/[(g+h)*(i-j)] (a+b)/(c+d) (e*f)/[(g+h)*(i-j)]/

//a+b c+d / e*f (g+h)*(i-j) a+b c+d/ e*f (g+h)*(i-j)//

//+ab +cd /*ef *g+h i-j

ab+ cd+/ ef* g+h i-j*//

//+ab +cd /*ef *+gh -ij

ab+ cd+/ ef* gh+ ij-*//

//+ab+cd/*ef*+gh-ij

ab+cd+/ef*gh+ij-*//

Se use el procedimiento que se use en la transformacin a mano y mientras no se tenga experiencia, es conveniente parentizar por completo la cadena infija para facilitar la transformacin: a*(b+c+d) ( a*[(b+c)+d]

VOLVER AL NDICE....Salto de pgina....ESCOLIOS tema 5

VOLVER AL NDICEPag 197. Frmula 5.1El superndice m indica que es longitud media. La n del denominador representa el nmero total de nodos del rbol. Toda una tarde buscando la frmula correcta por entender que esta n era el total de niveles...hasta llegar a esta misma con los nombres cambiados.

Figura 5.2: LI m = (21+52+33) / 11 = 1'90 (longitud de trayectoria interna mxima es 3).

Figura 5.3: LI m = (21+32+1.3) / 7 = 1'57 (longitud de trayectoria interna mxima es 3).

Pag 197. Segundo prrafoLongitud de la trayectoria interna (no confundir con la media): LI = (hi=1 ni i. Sumatorio desde i=1 hasta h (profundidad); donde ni es el nmero de aristas que llegan al nivel i (o nmero de nodos del nivel i).

Pag 198. Frmula 5.2La profundidad del rbol extendido siempre ser una unidad mayor que la del rbol de partida. La m del denominador representa el nmero total de nodos especiales del rbol.Figura 5.3: LE m = (01+12+53+24) / 8 = 3'125

*aadido*

Pag 201. Programa 5.1.Destacar la primera lnea. En una funcin, no un procedimiento. Albricias!!, por fin veo un ejemplo, encima recursivo, que contradice la definicin dada en Programacin I que exige que el valor devuelto por una funcin sea un valor simple (atmico). Nunca entend esa limitacin que impona el libro de PI: si podemos definir una funcin matemtica que, por ejemplo, dada una matrz devuelva su transpuesta, no existe limitacin terica (otra historia es lo que diga el compilador) para implementarla.

Recordatorio de Modula2. La sentencia WITH sirve para fijar el nombre del registro con el que se va a trabajar, de modo que en las lneas entre esta sentencia y su correspondiente END slo haya que escribir el nombre del campo y no registro.campo.

Si no se entiende correctamente la dinmica del programa, ejecutar demos\arb_perf_bal_r.exe del CD.

....Salto de pgina....Pag 202. Programa 5.2

Ser torpe, pero slo consigo entenderlo as:

PROCEDURE Perfec_balanceado(f:File;VAR k:Ptr_Nodo);

(*f: fichero con los datos a almacenar en el arbol*)

VAR w: INTEGER;

|(*****************************************************)

| PROCEDURE Insertar_Arbol_perf(w: INTEGER;VAR k:Ptr_Nodo);

| (*w:elemento a introducir en el arbol;k:raiz del arbol*)

| VAR numdch,numizq : INTEGER;

| |(*****************************)

| | PROCEDURE NumNodos(a: Ptr_Nodo):INTEGER;

| | (*Devuelve el numero de nodos del arbol apuntado por a*)

| | BEGIN

| | IF a=NIL THEN

| | RETURN 0

| | ELSE

| | RETURN 1+NumNodos(a^.izq)+NumNodos(a^.dch);

| | END

| | END NumNodos;

| |(***************************)

| BEGIN

| (*lectura hasta que termine la entrada de datos*)

| IF k#NIL THEN

| numdch:=NumNodos(k^.dch);

| numizq:=NumNodos(k^.izq);

| END;

| IF k=NIL THEN (*insertar*)

| ALLOCATE(k,SIZE(Nodo));

| k^.Dato:=w;

| k^.dch:=NIL;

| k^.izq:=NIL;

| ELSIF numdch=numizq THEN

| Insertar_Arbol_perf(w,k^.izq)

| ELSIF numizq>numdch THEN

| Insertar_Arbol_perf(w,k^.dch)

| END;

| END Insertar_Arbol_perf;

|(****************************************)

BEGIN (*principal del procedimiento Perfec_balanceado-*)

Reset(f) ReadWord;

WHILE ~f.eof DO

Insertar_Arbol_perf(w,k);

ReadWord(f,w);

END;

Close(f);

END Perfec_balanceado;

*aadido*

Pag 205. 5.3.1

Para estos 'rboles de expresin' creo sera ms descriptivo el nombre de 'arboles jerrquicos' (se usa este nombre en la literatura informtica?) pues es justo lo que hacen, describir grficamente una relacin de jerarqua de todas las unidades dependientes con sus respectiva(s) unidad(es) superiores. Por ejemplo, (aunque no siempre el rbol se podr construir binario), las relaciones jerrquicas en una estructura, empresa u organizacin estrictamente vertical (no existen dependencias entre iguales; paradigmas (aproximados): el ejrcito o el timo de la cadena o pirmide) o tambin por ejemplo el anlisis sintctico de una oracin (bien empleados y no en la mierda pedaggica que tuvimos que tragar todos los de mi generacin).

Pag 206.Y yo partindome los cuernos en el escolio de la pgina 182 para encontrar una generalizacin a partir de los tres mseros ejemplos que nos daban.

Como ejercicio para dibujar rboles, los dos mismos problemas planteados en el escolio mencionado. Como procedimiento mecnico, para no dejarme nada en el tintero, comienzo a pintar el rbol por la izquierda de la expresin. O sea, que en el primer rbol, lo primero que pinto es:

-

a b y a partir de ah, a donde me lleve la expresin, en este caso a un nodo / que apunta a -, etc.:

Una vez dibujado el rbol es muy conveniente realizar un recorrido en orden (IND) para comprobar que la expresin infija que se obtiene es la misma que la de partida.

....Salto de pgina....{[(a-b)/c]+d+e}*f (Si no se ven las aristas, pica: Ver / Diseo de pgina): *

+ f

+ e

/ d

- c

a b

Prefija: recorrido preorden (NID): *++/-abcdef

Postfija: recorrido postorden (IDN): ab-c/d+e+f*

a+b*c*[d+e/(f*g)]:

+

a *

b *

c +

d /

e *

f g

Prefija: recorrido preorden (NID): +a*b*c+d/e*fg

Postfija: recorrido postorden (IDN): abcdefg*/+**+

Pag 210 Primer prrafo.Si se dibuja a mano un rbol de bsqueda de una secuencia dada es muy importante respetar este criterio. Una vez pintados los tres primeros nodos, para cada nueva insercin preguntar siempre si es menor o mayor que raz y repetir la pregunta por cada nodo que se pase. Jams pintar un nodo a ojo de buen cubero, puesto que cuando el rbol tenga unos pocos nodos, se podra colocar como hijo de un padre de modo que respetase la norma 'menor a la izquierda, mayor a la derecha' (o viceversa), pero no sera el rbol de bsqueda de la secuencia de partida.

Pag 210. Penltima lnea del penltimo prrafo.Debera decir algo similar a: 'para lo cual, por respeto a la generalidad del programa 5.5, habr que apuntarlo previamente con un puntero auxiliar', pues se puede primero liberar el nodo y despus poner a NIL el apuntador. Es una operacin legal, a fin de cuentas (sobre la figura 5.11) si fuese ilegal para el enlace p, ocurrira lo mismo con q; tan puntero es uno como otro.

Pag 213. Segundo, tercer prrafo y figura 5.13El ejemplo de la figura no es muy ilustrativo, pues en ambas opciones el nodo que pasa al lugar del eliminado est dos niveles por abajo (cierto es que tal como estn pintados los subrboles 'rectngulos', se garantiza que no habr ningn mayor de los menores ni menor de los mayores diferentes a 45 y 77 respectivamente).

Otro ejemplo en la figura 5.10. Si el nodo a eliminar es el 13, tomar su lugar o bien el 12 (situacin similar a la anterior), enlace izquierdo de 12 pasar a apuntar a 9, derecho a 22 y derecho de 9 pasa a 10 (izquierdo de 9 sigue igual); o bien el 14, cuyo enlace izquierdo pasar a apuntar a 9, derecho a 22, izquierdo de 15 pasa a NIL y derecho no se modifica.

Pag 214. Primera lnea despus del programa.Dice: Dado que la bsqueda es dirigida...

Debe decir: Dado que la insercin es dirigida...

Es cierto que la bsqueda, as como la eliminacin y la insercin, son dirigidas; pero los dos primeros no pueden realizar ningn tipo de clasificacin.

Final de este prrafo: Si cualquiera de los dos rboles siguientes se leen estrictamente de izquierda a derecha, sin tener en cuenta en que nivel est un nodo, se observa que las dos mismas secuencias (con diferentes desrdenes) de partida se leen ordenadas: 2, 4, 9, 10, 12, 13, 14, 15, 16, 17, 18, 22, 23, 32, 42, 69, 99.

Pag 215. Mitad de la pgina, tercera secuencia.El rbol no es perfectamente balanceado, pues la rama izquierda del nodo 10 tiene 3 nodos y la derecha ninguno (difieren en ms de uno).

16

12 32

10 14 22 69

4 13 15 18 23 42 99

2 9 17

Si en la secuencia dada se intercambian, por ejemplo, el 9 y el 10, la secuencia pasa a tener un rbol de bsqueda perfectamente balanceado: 16, 12, 32, 9, 22, 14, 69, 4, 13, 18, 42, 10, 15, 23, 99, 2, 17.

16

12 32

9 14 22 69

4 10 13 15 18 23 42 99

2 17

Pag 215. Mitad de la pgina, prrafo bajo la tercera secuencia.La frase ' y las secuencias ordenadas, tanto crecientes como decrecientes....' nada tiene que ver con el rbol perfectamente balanceado que acabamos de ver. Debera ir en un punto y aparte. Se refiere a que si se forma el rbol de una secuencia ya ordenada, se produce una lista enlazada.

Pag 216. Tercera lnea.

Los nodos especiales sern en este caso los que insertaramos para ser apuntados por los enlaces que estn a NIL (sustituyendo estos enlaces). En resumidas cuentas: m = nmero de enlaces NIL del rbol.

Recordar que para calcular LE hay que aadir una unidad a la profundidad (valor mximo para el ndice i)

Pag 220. Prrafo final.Necesitar rebalanceo si bal(N)= -2. Esto significa que antes de la insercin bal(N)= -1, que es lo mismo que decir que su rama izquierda era un nivel ms profundo que la derecha (hD-hI).

Es muy importante recordar (yo siempre me olvido) el criterio que se da en la ltima lnea para la eleccin del nodo N.

Pag 221. ltimas dos lneas antes de la figura.Esta frase puede dar origen a confusiones; se refiere slo al nodo N. Si bal(NI)=-1 tambin habr que rebalancear, como ya se vio ms arriba, pero con la particularidad de que NI ser el nodo N a considerar.*aadido*

Pag 221. Figura 5.15Obsrvese que las alturas de cada rama son relativas. Si fueran absolutas desde la raz y de izquierda a derecha seran:

a) h, h-1, h-1.

b) h, h, h-1.

c) h 1, h, h-1.

Con estas alturas absolutas, se obtienen los mismos valores que los indicados en la figura.

*aadido*

Pags 222 a 228

En lo que resta, es preferible trabajar con los ejemplos de las figuras 5.21 a 5.25, realizando todos los pasos a mano. Ayuda si adems en estas figuras se aade a cada nodo el campo balance con el valor antes de la insercin en un color y en otro color despus de insercin.

El nico secreto que tiene el rebalanceo es conseguir ver cmo hay que retocar el rbol para restaurar las alturas. Vemoslo en la figura 5.17.

La situacin inicial es la de la subfigura a) sin el recuadro gris. N est cargado en altura por la izquierda, mientras que NI no. En el momento que insertemos el cuadro gris, NI pasa a estar cargado dentro de los lmites permisibles (bal(NI)= -1), mientras que N pasa a una situacin no admisible(bal(NI)= -2) . Bien. Vemos que en esta situacin hay tres subrboles implicados (los representados por rectngulos) que tienen profundidades distintas. Hemos de intentar dejarlos todos al mismo nivel o al menos dentro del margen que permite la definicin: un nivel de diferencia.

Para ello, bastara introducir un nodo en la rama derecha ms alta y eliminar otro por la izquierda ms alta, con lo que las alturas quedaran niveladas. A partir de aqu, slo hace falta tener en cuenta que se han de seguir respetando las relaciones de orden para que el rbol siga siendo uno de bsqueda...y que de cualquier nodo no pueden colgar ms que una rama por cada lado

Ojo que la nomenclatura LL, LR ... se establece en funcin de qu ramas estn cargadas de N y NI despus de la insercin. Por tanto, la expresin 'rebalanceo LL' (o incluso giro o rotacin LL) slo significa qu problema se quiere solucionar, no indica en modo alguno qu y cuntas rotaciones de nodos hay que realizar o sobre qu ramas se va a trabajar. De hecho, no hay manera de encontrar (al menos no lo encontr) un nemotcnico usando imgenes grficas jugando con rotaciones horarias (a derechas) y antihorarias o bien jugando con qu ramas son las que sufren asignaciones en los punteros.

Pag 230. Figura 5.21.Mucho, mucho ojo con este ejemplo. En todas las dems figuras el nodo N aparece como raz del subrbol representado, por lo que el puntero p lo apunta desde fuera. En cambio aqu el nodo N es el 4, por lo que el puntero p es el enlace izquierdo del nodo 5.

Por otra parte, el ejemplo permite comprobar que con el rebalanceo se cambian algunas relaciones xy para determinados pares (x, y). En el caso de x=2 e y=4 se ha pasado de la relacin 4 > 2 a 2 < 4. Tambien, el 5 tena como menor directo al 4, pasando despus a tener como menor al 2; pero todo esto carece por completo de relevancia El objetivo de los rboles de bsqueda, balanceados o no, es crear una estructura que permita localizar eficientemente una clave dada, no la relacin entre pares concretos.

*aadido*

Pag 237

Si he entendido bien, para hacerlo a mano no es necesario comerse tanto el coco en caso de supresin de un nodo. Las consideraciones de esta pgina estn pensadas para el programa.

Grficamente (a mano): se suprime directamente, realizando el correspondiente intercambio de posiciones (que pase a su lugar el menor de los mayores o el menor de los mayores) y una vez en esta situacin estudiar cmo quedan los campos balance, con cuidado porque puede ocurrir que el nodo ms profundo en el que balance no pertenezca a {-1,0,1} est en un nivel superior al del nodo suprimido/sustituto.

VOLVER AL NDICE....Salto de pgina....ESCOLIOS tema 6

VOLVER AL NDICEPag 243. Primera lnea del segundo prrafo.El calificativo multicamino puede dar lugar a confusin. Sea rbol binario, nonario, normal o B, el camino o trayectoria para llegar desde la raz a una clave determinada es siempre nico.

Adems, es cierto que en rboles de grado mayor que 2 de cada nodo puede salir ms de un camino o trayectoria, pero eso mismo ocurre en los de grado 2.

Pag 246. Primera lnea.Cuidado, logaritmo en base dos de un milln; no logaritmo decimal, cuyo valor sera desde luego 6.

*aadido* modificada la redaccin

Pag 247. Figura 6.1.Aqu parece que se aclara la afirmacin del primer prrafo de la pgina 197 segn la cual en los rboles B no coincide la longitud de trayectoria de un nodo con su nivel, pues para llegar a la clave 98 del nivel 2 hay que recorrer dos aristas, ms secuencialmente una pgina del nivel 1 y otra del nivel 2.

Aunque en puridad, siguiendo la definicin 5.6 (pag 196) al pie de la letra y lo que se dice al comienzo de la 246 de la que se sigue que cada pgina se puede considerar un surrbol degenerado, la longitud de trayectoria para una clave s coincidira con el nivel en el que est.

*aadido*

Pag 248. Segundo prrafo de 6.2.2.La clave mitad no es necesariamente la que ocupa el lugar central de la pgina (cosa adems imposible: por la definicin 6.1 todas las paginas llenas tendrn un nmero par de llaves). Si la clave a insertar lo es en la mitad izquierda de una pgina, la clave mitad ser la ms a la derecha de dicha mitad. Al contrario si le correspondiese insertarse en la mitad derecha.

Al final de este prrafo se dice: 'De hecho puede ser sta (la clave a insertar) la que sea necesario subir un nivel'. Esto ocurrira por ejemplo si en figura 6.3 se quiere insertar la clave 39 en vez de la 42. La subfigura c) quedara as: A: 30, 39; B y C: igual; D: 40, 45.

*aadido*

Pag 249 y siguientes y figura 6.4Resulta mucho ms claro si se intenta hacer a mano. Observar que el criterio de actuacin en caso de pgina llena es diferente segn sta sea pgina raz o no. En el segundo caso, explicado en el libro. En el primero, el elemento 'central' se queda en la raiz y el resto se desdobla a un nivel inferior (ver 6.4b y 6.4k)

Figura 6.4 f). Por qu se sube el 13?.

Si se subiese el 8, su pgina hija izquierda tendra slo la clave 4 y su hija derecha las claves 13, 22 y 28, vulnerando as la definicin de rbol B.

Si se subiese el 22, su hija izquierda tendra las claves 4, 8 y 13 y su hija derecha slo la 28; otra vez no se cumple la definicin, en esta ocasin por culpa de la hija derecha.

Figura 6.4 k) e i). En situaciones como sta, en la que desdoblar una pgina trae como consecuencia la creacin de una nueva raz, es muy buena prctica la indicada en la figura: realizar el desdoblamiento del nivel ms profundo dejando indicada la clave a insertar bajo su nodo padre, sin preocuparse de si tiene sitio o no.

Pag 258. Figura 6.9 y ss.Es muy conveniente repetir todos estos ejemplos a mano sustituyendo los nombres de los nodos A, B y C por claves numricas adecuadas que respeten las relaciones de orden entre nodos. De lo contrario es muy fcil confundirse.

*aadido* tras los exmenes.

Termino toda esta ladrillo con un 'copiar y pegar' de un correo que envi al foro y que qued sin respuesta.

Creo que ahora tengo una idea aproximada de por donde van los tiros (sin afinar demasiado).

Lo dicho, han terminado los exmenes y no tengo ni las ms mnimas ganas de volver sobre el asunto. Me permito el divertimento de no dar pistas para las respuestas a las dudas que planteo.

Hola a todos los que sigis vivos...

Antes de poder entrar en mi duda, una pequea discusin previa.

Cada pgina de un rbol B puede ser considerada como una lista enlazada (entre otros fragmentos, en 256: '...estos apuntadores horizontales tambin se presentaba implcitamente en los rboles B...'), por lo que la 'profundidad' de un elemento dado i (medida en enlaces totales) ser la suma de las aristas recorridas + los enlaces internos por los que se ha pasado. El que no se consideren estos enlaces internos como aristas, supongo que es debido a lo apuntado en el libro pero que no dan muchas pistas. Bien. Supongo que el puntero a pgina 0 (raz) est en memoria. Para localizar un elemento dado (pongamos que el 25 de la figura 6.4l) se trae la pgina completa desde memoria secundaria (normalmente imagino que coincidir con un mltiplo de pgina o un sector completo de H.D.), ahora se realiza una bsqueda secuencial y se determina que hay que traer la pgina apuntada por el puntero a la derecha del 24, etc, etc. Desde luego visto as, no se cumple lo dicho en la pgina 197 primer prrafo donde profundidad no coincide con nivel, pues en realidad deberamos ver las pginas como un subrbol (degenerado) en posicin vertical. Que no se haga as es una abstracin para simplificar la manipulacin de un rbol cuyos nodos son sectores o pginas de disco duro.

Bien, ahora viene mi duda. Qu utilidad o ventaja presentan los rboles BB y los BBS? o al menos para que se usan?. Conceptualmente no se diferencian en nada de los rboles B, excepto en el tamao mximo de claves por pgina y la posibilidad de usar un mismo puntero para generar un lista secuencial dentro de una pgina o para sealar un hijo dependiendo del campo booleano h. Especialmente lo que me desconcierta es la afirmacin en el segundo prrafo de la pgina 256 de que se usan principalmente en memoria principal. Si el rbol BB slo contiene datos y enlaces que ya estn en memoria principal, para qu complicarnos?. Tal vez por que los costes de rebalanceos sean menores que en AVL hasta el punto de compensar una mayor longitud de trayectoria mxima? (dudo que sea as, BBS son una generalizacin de AVL pgina 266).

Pues ahora salta otra duda. En la pgina 257 al principio se asegura que la longitud de trayectoria mxima para un rbol BB es 2[log n] y en la 259 se asegura lo mismo para los BBS, pero al final de la 257 afirma que la definicin de BB produce una asimetra en el crecimiento. Personalmente dudo que esto ocurra, como mucho, puede que sea mayor el coste de los rebalanceos en el caso de los BB al realizarse, quiz, ms; pero al final tanto uno como otro producen estructuras de crecimiento igual de ordenado. Alguien ms cree lo mismo?.

Y una ltima pregunta y yo para qu me preocupo de estas gilipolladas?. Debera estar durmiendo...como todos los que leis esto ahora.

r! infimticos.

Ceuta

Julio - septiembre 2001

VOLVER AL NDICE....Salto de pgina....Addenda

VOLVER AL NDICETEMA 2

Jerarqua de los rdenes de complejidad.

((1) ( ((log2+k n) ( ((log2 n)( ((n) ( ((nlog n) ( ((n2) ( ((n2+k) ( ((2n) ( (((2+k)n) ( ((n!), con k real no negativo

((1) ( ((log2+k n) ( ((log2 n) ( ((n) ( ((nlog n) ( ((n2) ( ((n2+k) ( ((2n) ( (((2+k)n) ( ((n!), con k real no negativoSuma de una sucesin aritmtica de n elementos (serie aritmtica):

(n= [n(primero + ltimo)] / 2 (la frmula es vlida independientemente de cual sea la diferencia d entre elementos consecutivos de la sucesin).

Si la serie empieza en uno y la diferencia es uno, la frmula se convierte en:

1+2+...+n ((n = n[(1+n)] / 2

Suma de una sucesin geomtrica de n elementos con razn r y coeficiente a (serie geomtrica):

ar0+ ar1+ ar2+ ...+ arn ( (ar n = [a(1- r n)] / (1-r).

f(lnx)dx = x(lnx-1) (sin olvidar los lmites de integracin). Puto Word (ya s que se puede, pero paso ahora de buscar cmo).

1/ln2 = loge

TEMA 5

En las frmulas que siguen: n = total de nodos, n i = nodos en nivel i, m = total nodos especiales, h = altura del rbol, g = grado del rbol.

Longitud de trayectoria media: LI m = ((hi=1 n i i ) / n (pag 197 y ss)

Longitud de trayectoria externa media: LE m = ((hi=1 m i i )/ mLongitud de la trayectoria interna : LI = (hi=1 ni i.

Longitud de la trayectoria interna : LE = (hi=1 mi i.

Nodos a aadir para convertir un rbol en rbol extendido: m = (g-1)n +1 *aadido*

La lnea que sigue la he modificado con respecto a la primera edicin pues contena un error descubierto posteriormente por Antonio Linde. Ver errata correspondiente

Nmero mximo de nodos rbol g-ario: Ng = (hi=1 g i

LE = 2n + LI (pag 199) Frmula de Hibbard (nmero de comparaciones): CNT = (1+1/n) Can -1

VOLVER AL NDICE....Salto de pgina....Fuente prog. 3.7 (balanceada)

VOLVER AL NDICEEditados tal como figuran en el libro de texto, aadiendo numeracin de lneas y llaves de diferentes colores que abarcan los distintos bucles.

Imprimir y pegar las hojas una a continuacin de la otra para tener el programa completo de un solo vistazo.

1 MODULE MezclaBalanceada;

2 FROM InOut IMPORT WriteInt,WriteString,WriteLn,ReadString;

3 FROM FileSystem IMPORT File,Close,Reset,WriteWord,ReadWord,Create;

4 FROM Strings IMPORT Assign;

5 CONST

6 long=20; (*para la prueba, no se utiliza en el algoritmo*)

7 N=6; (*numero de cintas*)

8 Nh=N DIV 2;

9 TYPE

10 secno=[1..N]; (*el ndice es el n de secuencia*)

11 TipoCadena=ARRAY [1..10] OF CHAR;

12 VAR i,j,mx,tx: secno;

13 L, (*nmero de corridas distribuidas*)

14 k1,k2: CARDINAL;

15 p,q,l,wfini1,wfini2,min,x,wx1,wx2:INTEGER;

16 fini, (* secuencia inicial de elementos *)

17 a,b,c,d : File; (* 4 secuencias en las que reparto *)

18 f : ARRAY secno OF File;(*Nmero de cintas en el proceso de clasificaci*)

19 nombre: ARRAY secno OF TipoCadena; (*Nombre de cada secuencia*)

20 entrada,nombrex: TipoCadena;

21 t, (*mapa de ndice de cintas*)

22 ta: ARRAY secno OF secno;

23 f1: prueba; (*para la prueba*)

24 eor,encontrado:BOOLEAN;

25 wx:ARRAY secno OF INTEGER; (*vector de elementos ledos de secuencias*)

26 fin:ARRAY secno OF INTEGER; (*si fin[i]=1 se ha alcanzado eor de la

secuencia f[i]*)

(***********************************************************)

27 PROCEDURE ListSec(VAR f: File);28 VAR w:INTEGER;

29 BEGIN

30 Reset(f);

31 ReadWord(f,w);

32 WHILE ~f.eof DO

33 WriteInt(w,3);

34 ReadWord(f,w);

35 END;

36 WriteLn

37 END ListSec;

(************************************************************)

38 PROCEDURE copiado(VAR x,y:File; VAR eor:BOOLEAN;wx1:INTEGER;VAR wx2:INTEGER);

(*Copia el valor de x en y;lee el primero de x y determina si es fin de corrida*)

39 BEGIN

40 WriteWord(y,wx1);

41 ReadWord(x,wx2);

42 eor:=(x.eof) OR (wx2