Apunte TDA versión preliminar Concepto de Tipo de dato abstracto: La abstracción es el mecanismo que permite seleccionar partes de un todo complejo para su consideración, ignorando el resto. Esto permite filtrar aquellos aspectos relevantes, y obtener soluciones más generales. El concepto de abstracción nos remite a la posibilidad de considerar la resolución de un problema sin tener en cuenta los detalles por debajo de cierto nivel . El concepto de Tipo de Dato Abstracto (TDA en castellano, ‘Abstract Data Type’ o ADT en inglés) surgió para facilitar el trabajo con tipos de datos haciendo abstracción de la implementación de los mismos. Los TDA constituyen una forma de generalización y encapsulamiento de los aspectos más importantes de la información que se debe manejar en la resolución de un problema, sin considerar las cuestiones relativas a la implementación. Un TDA está dado por un grupo de datos que cumplen cierta condición especificada para el TDA, más un conjunto de operaciones que representan el comportamiento del TDA. Un TDA está caracterizado por un conjunto de operaciones (procedimientos y funciones) denominados usualmente su interfaz pública y representan el comportamiento del TDA; mientras que la implementación privada del TDA está oculta al programa cliente que lo usa La entidad TDA exporta las características de forma de las operaciones. La implementación de la estructura del TDA, y de las operaciones propias son privadas por cuestiones básicamente de abstracción; esto significa que no se permite acceso ni visibilidad a la implementacion de un TDA. Esta parte oculta está constituída por la maquinaria algorítmica que implementa la semántica de los operadores. De este modo un TDA encapsula ciertos tipos de datos en cuanto a la definición del tipo y todas las operaciones del mismo en una sección del código. Un TDA define así una nueva clase de concepto que puede manejarse con independencia de la estructura de datos para representarlo. Es una generalización del concepto de tipo de dato básico y sus operaciones primitivas. Es decir, TDA = Representación (estructuras de datos) + Operaciones (métodos) Se debe, como se ha dicho, distinguir entre la implementación de un TDA y su especificación. Una es el qué y el otro el cómo debe hacerlo. Cuando nos preocupamos de la implementación estamos hablando de una estructura de datos, no de un TDA. La especificación de un TDA es la descripción del comportamiento del mismo. Debe formalizarse. Indica qué hace el TDA. Una especificación debe ser formal. En las especificaciones constructivas de las primitivas se detallan las pre y postcondiciones de cada procedimiento de acceso al TDA. Las precondiciones de una operación representan los requisitos que se deben cumplir para que la operación se lleve a cabo. Las postcondiciones expresan las condiciones que se verificarán para el TDA luego de llevada a cabo la operación correspondiente. La implementación es la forma específica en que se expresan las operaciones. Aquí se considerará la estructura de datos más conveniente. Está dado por un grupo de instrucciones a ser ejecutadas por la computadora, y se escribe en uno o más lenguajes de programación. Cada implementación corresponde a alguna especificación. La representación es la forma concreta en que se representan los datos en un determinado lenguaje de programación. Apunte TDA versión preliminar Cada TDA especificado formalmente está acompañado por un conjunto de axiomas, que explicitan de manera rigurosa las características propias de las primitivas, de modo tal que no sea posible confundir un TDA con otro. (Por ejemplo la primitiva Alta o Insertar aparece en diversos TDA, pero se lleva a cabo de diferente manera en cada TDA (vale decir, modifica el estado del TDA de modo diferente para cada TDA); lo que caracteriza al Alta para cada TDA se explicita con axiomas diferentes para cada TDA. El conjunto de axiomas que definen un TDA debe ser completo en el sentido de definir el resultado de todas las aplicaciones permisibles de las operaciones sobre el TDA y también completo en el sentido de definir operaciones que permitan construir todas las posibles instancias o situaciones del TDA. Las primitivas u operaciones básicas de un TDA pueden ser de diversos tipos, por ejemplo: Constructores y destructor. Procedimientos que modifiquen el estado del TDA. Selectores (procedimientos que sirven para informarnos cómo está el TDA, sin modificarlo). Iteradores (operadores que guían el recorrido sobre la estructura en curso. Hay iteradores activos, que pueden modificar las estructuras, y pasivos,que no las modifican). El TDA Vector: Un TDA vector es una estructura monolítica (no reestructurable), acotada por definición que está compuesta por un número finito de elementos de un tipo base, siendo todos del mismo tipo, a los cuales se accede mediante un segundo tipo, llamado índice que es de tipo conjunto finito. No se pueden ni borrar ni insertar elementos de un vector. Especificación formal del TDA TVector: Nomenclatura usada: V : conjunto de los TVector I: conjunto de subíndices válidos X: conjunto de tipo base Operaciones (Especificaciones sintácticas): Crear: Pre : Ninguna Post : Se crea una instancia del Vector ->V[X] Destruir: Pre : el vector debe haber sido creado Post : ninguna V -> Cambiar: Pre : el vector debe haber sido creado Post : el vector se modifica por la alteración del i-ésimo elemento Apunte TDA versión preliminar Cambiar: Vector[X] × X × I -> V Valor: Devuelve el valor almacenado en la i-ésima posición del vector Pre : el vector debe haber sido creado Post : ninguna Vector[X] × I ->X Axiomas: V V є (X, I); i, j є X; x є I Valor(CreateVector(), i) = error Valor(Cambiar(v, i, x), j) = x si i=j , Valor(Cambiar(v, i, x), j) = Valor(v, j) si i≠j Implementación de un TDA vector: La implementación más sencilla es con una estructura array, aunque también puede utilizarse alguna forma de estructura de lista de nodos ligada con punteros. TDA Lista Una TDA lista es un TDA contenedor secuencial de elementos de un tipo base, para los cuales están especificadas las siguientes operaciones básicas: crear, destruir, alta en una posición válida, baja de una posición válida, determinación del elemento ubicado en una posición válida. A diferencia de un TDA vector, y según se especifica en los axiomas, el alta o la baja en una determinada posición modifica los valores correspondientes a las posiciones de los elementos posteriores a la posición elegida para el alta. En una lista puede haber repeticiones; el alta de un elemento siempre aumenta el número de elementos almacenados. Nomenclatura usada: Lista: conjunto de TLista G: tipo base de elementos almacenados Se ha considerado cada elemento asociado a un valor entero que es su posición. No confundirlo con el elemento que se utiliza como índice en un vector. El TDA Lista no tiene estructura monolítica Operaciones básicas o primitivas: (Este es un posible grupo de primitivas para el TDA Lista; en los distintos textos que se consulten se pueden encontrar variaciones de las primitivas, o bien puede elegirse desarrollar una lista que mantenga el orden de sus elementos) Crear: Precondición: ninguna Postcondición: lista creada y vacía -> LISTA[G] Destruir: Precondición: lista creada Postcondición: ninguna LISTA[G] x -> Apunte TDA versión preliminar Destruye la lista Insertar: Agrega un elemento en la posición especificada Precondición: la lista debe haber sido creada, y la posición elegida debe estar entre 1 y el total de elementos más uno (caso de inserción al final). Postcondición: la lista resulta modificada por inserción del elemento LISTA[G] x INTEGER x G - LISTA[G] Remover: Elimina el elemento de la posición especificada. Precondición: la lista debe haber sido creada, y la posición elegida debe estar entre 1 y el total de elementos . Postcondición: la lista resulta modificada por la eliminación del elemento LISTA[G] x INTEGER -> LISTA[G] Item: Retorna el elemento de la posición especificada, sin modificar la lista. Precondición: la lista debe haber sido creada, y la posición elegida debe estar entre 1 y el total de elementos . Postcondición: ninguna LISTA[G] x INTEGER -> G Total: Retorna un valor entero que indica el número de elementos contenidos en la lista Precondición: la lista debe haber sido creada. Postcondición: ninguna LISTA[G] -> INTEGER Posición: Devuelve la primera posición de la lista donde se encuentre el elemento; si no está en la lista, devuelve total +1. Precondición: lista creada Postcondición: ninguna LISTA[G] x G -> INTEGER Axiomas : Para todo x,y: G; i,j: INTEGER; L: LISTA[G] se verifica: total(crear) = 0 ( la lista se construye vacía). total(insertar(L, i, x)) = total(L) + 1 ( por efecto de la inserción de un elemento, el total de elementos aumenta en 1) remover(insertar(L, i, x), i) = L (si se compone una inserción de un elemento en cierta posición con la eliminación del elemento de la misma posición, la lista que da en el estado previo a la inserción). si i - j insertar(insertar(L, i, x), j+1, y) = insertar(insertar(L, j, y), i, x) ( el orden de los elementos en la lista está determinado por las posiciones donde se hicieron las altas). Apunte TDA versión preliminar item(insertar(L, i, x), i) = x (si se inserta un elemento en la posición i-ésima de la lista y luego se efectúa ítem de esa posición, se obtiene el elemento insertado). si j < i entonces item(L, j) = item(remover(L, i), j) (al eliminar un elemento de la posición i no se afecta la posición de los elementos en las posiciones de la 1 a la i-1, si j>1). si j > i entonces item(L, j) = item(remover(L, i), j -1) ( al eliminar un elemento de la posición i disminuye en 1la posición de los elementos en las posiciones i+1 en adelante). Posición((L, x) = min i {item(L, i) = x or i = total(L) + 1}: devuelve la primera posición de la lista donde se encuentre el elemento, si no está en la lista, devuelve total +1.) Implementación del TDA lista: Puede implementarse un TDA Lista en un array (poco eficiente) o, como se hace a menudo, usando una estructura de lista de nodos ligados con punteros. TDA Pila (Stack) Una pila es un contenedor de objetos que se insertan y se eliminan siguiendo el principio ‘Ultimo en entrar, primero en salir’ (L.I.F.O.= ’Last In, First Out’). a característica más importante de las pilas es su forma de acceso. En ese sentido puede decirse que una pila es una clase especial de lista en la cual todas las inserciones (alta ,apilar o push) y borrados (baja, desapilar o pop) tienen lugar en un extremo denominado cabeza o tope. El Tope de la pila corresponde al elemento que entró en último lugar, es decir que saldrá en la próxima baja. En lenguajes de alto nivel, es muy importante para la la eliminación de la recursividad, análisis de expresiones, etc. En lenguajes de bajo nivel es indispensable y actúa constantemente en todos los lenguajes compilados y en todo el sistema operativo. Se puede considerar una pila como una estructura ideal e infinita, o bien como una estructura finita. Operaciones básicas o primitivas para pilas infinitas Nomenclatura usada: S : conjunto de los TPila G: conjunto de tipo base Crear: Crea la pila Precondicion : no tiene Postcondicion : una pila vacía preparada para ser usada. ->PILA[G] Destruir: Destruye la pila Precondicion : la pila debe haber sido creada Apunte TDA versión preliminar Postcondicion : no tiene PILA[G]-> Push: Realiza el alta en la pila de un elemento pasado por argumento (que se ubicará en el tope) . Precondicion : la pila debe haber sido creada. Postcondicion : la pila modificada con la inserción del nuevo elemento PILA[G] x G -> PILA[G] Pop: Elimina el elemento del tope de la misma. Precondicion : la pila , ya creada, no debe estar vacía. Postcondicion : pila modificada por la eliminación del elemento del tope. PILA[G] ->PILA[G] Tope: Retorna el valor del tope de la pila Precondicion : la pila , ya creada, no debe estar vacía. Postcondicion: no tiene PILA[G]-> G Vacia: Devuelve un valor indicando si la pila está vacía Precondicion : la pila debe haber sido creada Postcondicion : no tiene PILA[G] -> BOOLEAN Axiomas: Tope(Push(s, x)) = x (si se hace top luego de push, se obtiene el elemento insertado con ese push) Pop(Push(s, x)) = s (si se compone push con pop, la pila vuelve al estado previo al push) Vacia(Crear)=true (la pila se crea vacía) Vacia(Push(s, x)) =false (luego de hacer un push la pila no está vacía) Operaciones elementales para pilas finitas: A las operaciones expuestas para pilas infinitas se le agrega la primitiva Llena : retorna un valor indicando si la estructura de la pila está llena. Precondiciones : la pila debe haber sido creada. Postcondiciones: no tiene. Además, en la operación Push, se modifican las precondiciones. Precondición de la operación Push para pilas finitas: la pila debe haber sido creada y no estar llena. Apunte TDA versión preliminar Implementaciones más habituales de las pilas: Utilizando un array, o bien mediante una lista ligada (con punteros), según se muestra en códigos adjuntos. TDA Cola Un TDA cola es un contenedor de objetos que se insertan y se eliminan siguiendo el principio ‘Primero en entrar, primero en salir’ (F.I.F.O.=’First In, First Out’). En ese sentido puede decirse que una cola es una lista con restricciones en el alta (encolar o enqueue) y baja (desencolar, dequeue). El Frente (FRONT) de la cola corresponde al elemento que está en primer lugar, es decir que es el que estuvo más tiempo en espera. El Fondo (END) de la cola corresponde al último elemento ingresado a la misma. Se puede considerar una cola como una estructura ideal e infinita, o bien como una estructura finita. El TDA cola se usa como parte de la solución de muchos problemas algorítmicos, y en situaciones tipo ‘productor-consumidor’, cuando una parte de un sistema sistema produce algún elemento otra ‘consume’ más lentamente de lo que es producida, por lo cual los elementos esperan en una cola hasta ser consumidos. Operaciones básicas o primitivas para colas infinitas Nomenclatura usada: COLA: conjunto de los TCola G: conjunto base Crear o New : Crea la cola Precondicion : no tiene Postcondicion : una cola vacía preparada para ser usada. -> COLA[G] Destruir: Destruye la cola Precondicion : la cola debe haber sido creada Postcondicion : no tiene COLA[G]-> Frente o Front : Retorna el valor del primer elemento de la cola Precondicion: la cola , ya creada, no debe estar vacía. Postcondicion: no tiene COLA[G] ->G Encolar o Enqueue : Da de alta en la cola a un elemento (que se ubicará al fondo) pasado por argumento Precondicion : la cola debe haber sido creada. Postcondicion : la cola modificada con la inserción del nuevo elemento Apunte TDA versión preliminar COLA[G] x G -> COLA[G] Desencolar o Dequeue: Elimina el elemento del frente de la misma. Precondicion : la cola , ya creada, no debe estar vacía. Postcondicion : cola modificada por la eliminación del elemento del frente. COLA[G] -> COLA[G] Vacia o Empty : Devuelve un valor lógico indicando si la cola está vacía. Precondicion : la cola debe haber sido creada Postcondicion : no tiene COLA[G] -> BOOLEAN Axiomas : El cumplimiento de estos axiomas asegura que el TDA funcione según la descripción realizada antes Para todo x: G, q: COLA[G] Vacia(Crear)=true (al crear una cola siempre está vacía). Vacia(Acolar(q,x))=false (si a una cola se le añade un elemento la cola no está vacía). si Vacia(q),entonces Frente(Acolar(q,x))=x (un alta en cola vacía modifica el frente de la misma). si Vacia(q)= false entonces Frente(Acolar(q, x))=Frente(q) (alta en cola no vacía no modifica el frente) si Vacia(q)= true entonces Deascolar(Acolar(q, x))=q (si la cola está vacía y se compone un alta con una baja, la cola quedará en el estado original) si Vacia(q)=false entonces Desacolar(Acolar(q, x)) = Acolar(Desacolar(q), x) (si la cola no está vacía, la composición de un alta de x con una baja es idéntica a la composición de una baja con un alta de x) Operaciones elementales para colas finitas: A las operaciones expuestas para colas infinitas se le agrega la primitiva Llena : retorna un valor indicando si la estructura de la cola está llena. Precondicion : la cola debe haber sido creada. Postcondicion: no tiene. Además, en la operación Encolar, se modifican las precondiciones. Precondición de la operación Encolar para colas finitas: la cola debe haber sido creada y no estar llena. Apunte TDA versión preliminar Implementaciones más habituales de las colas: Utilizando un array ‘circular’ si se prefiere una implementación en memoria contigua, o bien mediante algún tipo de estructura de lista ligada con punteros. TDA Cola con prioridad. Una cola con prioridad es un Tipo de Dato Abstracto contenedor, en donde los elementos se insertan en la posición asociada a su prioridad, y se dan de baja como en una cola común. Es decir que no se cumple el principio de ‘primero en entrar, primero en salir’, sino que los elementos se acomodan en función del valor de prioridad asociado. Entre aquellos de la misma prioridad, sí se verifica que el último se ubica al final de los de su misma prioridad. Sus primitivas son: INSERTAR SUPRIMEMINIMO (o SUPRIME_MAXIMO, dependiendo del convenio asumido) DEVUELVEMINIMO (o DEVUELVE_MAXIMO dependiendo del convenio asumido) A cada objeto en la cola, se le asocia una prioridad, según una función de la forma: Prioridad : Conjunto de objetos -> Conjunto linealmente ordenado (por ejemplo, Z) Implementación del TDA Cola con Prioridad : puede utilizarse un array (muy poco eficiente), o una estructura de lista ligada (poco eficiente), pero lo más conveniente es usar una estructura heap o montículo. TDA Conjunto (set) Un conjunto (set en inglés) es una colección de elementos todos diferentes entre sí; en un conjunto no puede estar dos veces el mismo elemento. Es decir que el alta de un elemento no siempre provoca el aumento del número de elementos contenidos en el conjunto. Entonces, debe haberse definido una relación de igualdad entre elementos de un conjunto. Primitivas del TDA Conjunto: Nomenclatura usada: Set: conjunto de TConjunto G. Tipo base del TConjunto Crear: Crea un conjunto vacío Precondición: no tiene Postcondición: conjunto creado vacío ->SET[G] Destruir: Destruye el conjunto Precondición: el conjunto debe existir previamente Postcondición: ninguna SET[G] -> Insertar: Agrega un elemento nuevo al conjunto Apunte TDA versión preliminar Precondición: el conjunto debe haber sido creado y el elemento no debe estar previamente en el conjunto Postcondición: conjunto modificado por el agregado de un nuevo elemento. SET[G] X G SET[G] Remover: Elimina un element del conjunto Precondición: el conjunto debe haber sido creado, y el elemento debe existir previamente en él. Postcondición: conjunto modificado por la eliminación de un elemento. SET[G] X G SET[G] Pertenece: Retorna un booleano indicando si un elemento está o no en el conjunto. Precondición: el conjunto debe haber sido creado. Postcondición: no tiene SET[G] X G -> BOOLEAN Vacío: Devuelve un valor lógico indicando si el conjunto está vacío. Precondición: el conjunto debe haber sido creado. Postcondición: ninguna SET[G] -> BOOLEAN Axiomas: Para todo x, y: G, S: SET[G] se verifica: vacio(crear)=true (el conjunto se crea vacío) vacio(insertar(S,X))= false (si se realiza un alta, no está vacío) pertenece(insertar(S, X), X)=true pertenece(remove(S, X), X)=false si y=x entonces insertar(insertar(S, X), Y) = insertar(insertar(S, Y), X) (al insertar dos veces el mismo elemento, el conjunto queda igual) Nota: existen otras operaciones entre conjuntos que son más avanzadas Algunas son: Union: SET[G] x SET[G] SET[G] Une el conjunto dado con el conjunto S. Interseccion: SET[G] x SET[G] SET[G] Intersecta el conjunto dado con el conjunto S. Diferencia: SET[G] x SET[G] SET[G]: Halla la diferencia entre el conjunto dado y el conjunto S. Igual: SET[G] x SET[G] SET[G] Determina si el conjunto dado es igual al el conjunto S. Apunte TDA versión preliminar Implementación del TDA Conjunto: El TDA conjunto se puede implementar de muy diversas formas: mediante arrays (muy poco eficiente), con listas de nodos ligadas con punteros (poco eficiente) o bien mediante la estructura de árbol binario de búsqueda, o árbol AVL, o árbol rojinegro,o árbol de m vías,o árbol 2-3, o árbol B (de modos mucho más eficientes). EL TDA ARBOL Un TDA Arbol es un TDA contenedor en el cual los elementos se ligan entre sí por un orden jerárquico, según lo especifican las primitivas del mismo. En este curso no se desarrollará este TDA. Primitivas del TDA Arbol (Usaremos un valor especial ARBOL_VACIO para el caso en que el árbol no contenga nodos, y NODO_NULO para expresar que un nodo no existe.) CREAR_Arbol: crea un árbol. Precondición : no tiene Postcondición.: el árbol vacío. DESTRUIR. libera los recursos que mantienen el árbol . Precondición: el árbol debe haber sido creado PADRE (de un nodo): Esta función recibe el valor de un nodo y devuelve el padre del nodo en el árbol. (Si el nodo no tiene padre, devuelve NODO_NULO) Precondición: el árbol debe haber sido creado y el nodo pasado al método no es nulo . Postcondición: ninguna. HIJO_IZQUIERDA(de un nodo): Devuelve el descendente más a la izquierda en el siguiente nivel del nodo recibido en el árbol. Devuelve NODO_NULO si el nodo recibido no tiene hijo a la izquierda. Precondición: el árbol debe haber sido creado y el nodo recibido no es nulo. Postcondición: ninguna. HERMANO_DERECHO(de un nodo): Devuelve el descendiente (a la derecha del nodo recibido) del padre del nodo, en el árbol Precondición : el árbol debe haber sido creado y el nodo recibido no es nulo. Postcondición: no tiene . RAIZ(T). Devuelve el nodo que está en la raíz del árbol o NODO_NULO si el árbol está vacío. Precondición: el árbol debe haber sido creado. Postcondición: no tiene. INSERTAR_HIJO_IZQUIERDA (de un nodo determinado): Inserta un árbol recibido recibido como hijo a la izquierda de un nodo determinado que pertenece al árbol . Precondición : el árbol debe haber sido creado, y no estar vacío y el nodo recibido no es nulo. Postcondición: el árbol alterado con el nuevo nodo agregado Apunte TDA versión preliminar INSERTAR_HERMANO_DERECHA(de un nodo determinado): Inserta el árbol recibido como hermano a la derecha de un nodo que pertenece al árbol . Precondición : el árbol debe haber sido creado, y no estar vacío y el nodo recibido no es nulo. Precondición : el árbol ha sido creado y no está vacío y el nodo recibido no es nulo. PODAR_HIJO_IZQUIERDA(de un nodo determinado): Devuelve el subárbol con raíz hijo a la izquierda del nodo recibido. Al nodo recibido se le elimina el hijo izquierdo.del árbol Precondición : el árbol ha sido creado y el nodo recibido no es nulo. Postcondición: árbol alterado por la eliminación del subárbol. PODAR_HERMANO_DERECHA: idem operación anterior, pero a derecha TDA ARBOL BINARIO (esto no es la estructura Arbol binario de búsqueda, o BST) Un árbol binario un árbol cuyos nodos tienen a lo sumo dos hijos o bien es un árbol nulo. Los hijos de un árbol binario se indican como hijo izquierdo e hijo derecho. Un árbol binario puede definirse como un árbol que en cada nodo puede tener como máximo grado 2 (máximo dos hijos). TDA Arbol Binario: Para construir el TDA Arbol Binario bastaría con utilizar las primitivas de los árboles generales pero dado la gran importancia y peculiaridades que tienen este tipo de árboles, construiremos una serie de operaciones específicas. Consideraremos las siguientes: CREAR: Crea un árbol vacío. Precondición: ninguna Postcondición : árbol creado y vacío. DESTRUIR: Libera los recursos que mantienen el árbol. Precondición: el árbol debe haber sido creado. Postcondición: ninguna PADRE(de un nodo determinado) : Devuelve el padre del nodo recibido. En caso de no existir el padre, devuelve NODO_NULO. Precondición : el árbol debe haber sido creado y el nodo recibido no es NODO_NULO. Postcondición : ninguna HIJO_IZQUIERDO(de un nodo determinado): Devuelve el hijo a la izquierda del nodo recibido o NODO_NULO si no existe . Precondición: el árbol debe haber sido creado y el nodo recibido no es NODO_NULO. Postcondición : ninguna. HIJO_DERECHO(de un nodo determinado): Devuelve el hijo a la derecha del nodo recibido o NODO_NULO si no existe . Precondición: el árbol debe haber sido creado y el nodo recibido no es NODO_NULO. Postcondición: ninguna. Apunte TDA versión preliminar RAIZ: Devuelve el nodo que está en la raíz del árbol o NODO_NULO si el árbol es nulo. Precondición: el árbol debe haber sido creado. Postcondición: ninguna INSERTAR_HIJO_IZQUIERDA(recibe un árbol y un nodo determinado): Inserta el árbol como hijo a la izquierda del nodo. Si ya existe el hijo a izquierda, la primitiva se encarga de que sea destruído junto con sus descendientes. Precondiciones: el árbol recibido no es ARBOL_VACIO y el nodo no es NODO_NULO. Postcondición: Arbol modificado por la inserción del nuevo nodo INSERTAR_HIJO_DERECHA(recibe un árbol y un nodo determinado): Inserta el árbol como hijo a la derecha del nodo. Si ya existe el hijo a derecha, la primitiva se encarga de que sea destruído junto con sus descendientes. Precondiciones: el árbol recibido no es ARBOL_VACIO y el nodo no es NODO_NULO. Postcondición: árbol modificado por la inserción del nuevo nodo PODAR_HIJO_IZQUIERDA(de un nodo determinado): Devuelve el subárbol con raíz hijo a la izquierda del nodo recibido, al cual se le quita el subárbol izquierdo. Precondición: el árbol debe haber sido creado y el nodo recibido no es NODO_NULO. Postcondición: árbol modificado por el borrado de un nodo PODAR_HIJO_DERECHO(de un nodo determinado): Devuelve el subárbol con raíz hijo a la derecha del nodo recibido, al cual se le quita el subárbol derecho. Precondición: el árbol debe haber sido creado y el nodo recibido no es NODO_NULO. Postcondición: árbol modificado por el borrado de un nodo Implementación de un TDA Arbol binario: Se puede utilizar una tabla, o bien alguna estructura arborescente, pero no una estructura árbol binario de búsqueda, ya que, como se puede observar, entre las primitivas del TDA Arbol binario están las que permiten insertar a la derecha o izquierda de un nodo, eliminando lo que hubiera previamente, y esto habilita a quebrar el ordenamiento propio de la estructura ABB, contraviniendo las reglas de funcionamiento de la misma.