CC 1002 Introduccin a la Programacin Clase 13

  • Slides: 25
Download presentation
CC 1002: Introducción a la Programación Clase 13 : Caso de Estudio II Nelson

CC 1002: Introducción a la Programación Clase 13 : Caso de Estudio II Nelson Baloian, José A. Pino

Problema • Suponga que desea mantener el registro de un conjunto de personas (descritas

Problema • Suponga que desea mantener el registro de un conjunto de personas (descritas por nombre y RUT, donde nombre es un texto y RUT es un numero entero). La cantidad de personas es a priori indeterminada, y se quiere implementar las funcionalidades de: • buscar personas en el registro, • agregar personas al registro, • borrar personas del registro, • evitar tener personas en el registro con RUT duplicado, y • ordenar un conjunto de personas de acuerdo a su RUT. .

Definiciones import estructura # persona: rut(int) nombre(str) estructura. crear("persona", "rut nombre") # nodo: valor(persona)

Definiciones import estructura # persona: rut(int) nombre(str) estructura. crear("persona", "rut nombre") # nodo: valor(persona) izq(nodo) der(nodo) estructura. crear("nodo", "valor izq der") # identificador para nodos vacios nodo. Vacio = None # crear. Nodo: persona nodo -> nodo # devuelve un nodo con datos de valor y los nodos izq # y der, respectivamente # ejemplo: crear. Nodo(persona(0, "a"), nodo. Vacio, #nodo. Vacio) devuelve nodo(persona(0, "a"), nodo. Vacio, #nodo. Vacio) def crear. Nodo(valor, izq, der): return nodo(valor, izq, der)

Tests # Test assert crear. Nodo(persona(0, "a"), nodo. Vacio,  nodo. Vacio) == nodo(persona(0,

Tests # Test assert crear. Nodo(persona(0, "a"), nodo. Vacio, nodo. Vacio) == nodo(persona(0, "a"), nodo. Vacio, nodo. Vacio) # vacio: nodo -> bool # devuelve True si el arbol binario esta vacio # ejemplo: vacio(nodo. Vacio) devuelve True def vacio(nodo): return nodo == nodo. Vacio # Test assert vacio(nodo. Vacio) == True

ABB # crear. ABB: None -> nodo # devuelve un ABB vacio def crear.

ABB # crear. ABB: None -> nodo # devuelve un ABB vacio def crear. ABB(): return nodo. Vacio

Ejemplo gráfico de un ABB RUT, Nombre, izq, der

Ejemplo gráfico de un ABB RUT, Nombre, izq, der

Buscar Nombre # buscar. Nombre: nodo int -> str # busca el nodo de

Buscar Nombre # buscar. Nombre: nodo int -> str # busca el nodo de un ABB raiz cuyo rut es un. RUT y #devuelve el texto asociado # al nombre en dicho nodo. Si rut no esta en el ABB #devuelve "" # ejemplo: # si ABB = crear. Nodo(15, "Juan", nodo. Vacio, #crear. Nodo(24, "Ivan", nodo. Vacio)) # entonces buscar. Nombre(ABB, 24) devuelve "Ivan"

Buscar Nombre def buscar. Nombre(raiz, un. RUT): # Caso base: buscar en un arbol

Buscar Nombre def buscar. Nombre(raiz, un. RUT): # Caso base: buscar en un arbol vacio if vacio(raiz): return "" else: if un. RUT == raiz. valor. rut: return raiz. valor. nombre if un. RUT < raiz. valor. rut: return buscar. Nombre(raiz. izq, un. RUT) else: #un. RUT > raiz. valor. rut return buscar. Nombre(raiz. der, un. RUT)

Buscar Nombre - Tests # Tests: suponiendo ABB creado según ejemplo assert buscar. Nombre(ABB,

Buscar Nombre - Tests # Tests: suponiendo ABB creado según ejemplo assert buscar. Nombre(ABB, 24) == "Ivan" assert buscar. Nombre(ABB, 50) == ""

Imprimir. ABB # imprimir. ABB: nodo -> str # devuelve un String con los

Imprimir. ABB # imprimir. ABB: nodo -> str # devuelve un String con los rut y nombres en el ABB raiz, ordenados # por rut # ejemplo: considerando el ABB siguiente: # 15, Juan # 1, Gustavo # 24, Ivan # imprimir. ABB(ABB) devuelve "RUT: 1 Nombre: Gustavo; RUT: 15 #Nombre: Juan; RUT: 24 Nombre: Ivan; "

Imprimir. ABB def imprimir. ABB(raiz): if raiz == nodo. Vacio: return "" else: return

Imprimir. ABB def imprimir. ABB(raiz): if raiz == nodo. Vacio: return "" else: return imprimir. ABB(raiz. izq) +"RUT: " + str(raiz. valor. rut) + " Nombre: " + raiz. valor. nombre + "; " + imprimir. ABB(raiz. der)

Insertar. ABB # insertar. ABB: persona nodo -> nodo # inserta un nodo con

Insertar. ABB # insertar. ABB: persona nodo -> nodo # inserta un nodo con atributo valor en el # ABB raiz # ejemplo: ver explicacion del profesor def insertar. ABB(valor, raiz):

Insertar. ABB def insertar. ABB(valor, raiz): if raiz == nodo. Vacio: return crear. Nodo(valor,

Insertar. ABB def insertar. ABB(valor, raiz): if raiz == nodo. Vacio: return crear. Nodo(valor, nodo. Vacio) else: # Test: no se pueden insertar rut repetido assert raiz. valor. rut != valor. rut # Insercion if valor. rut < raiz. valor. rut: return crear. Nodo(raiz. valor, insertar. ABB(valor, raiz. izq), raiz. der) else: # valor. rut > raiz. rut return crear. Nodo(raiz. valor, raiz. izq, insertar. ABB(valor, raiz. der))

Insertar. ABB - Tests juan = persona(15, "Juan") ivan = persona(24, "Ivan") gustavo =

Insertar. ABB - Tests juan = persona(15, "Juan") ivan = persona(24, "Ivan") gustavo = persona (1, "Gustavo") ABB = crear. ABB() assert insertar. ABB(juan, ABB) == crear. Nodo(juan, nodo. Vacio) ABB = insertar. ABB(juan, ABB) assert insertar. ABB(ivan, ABB) == crear. Nodo(juan, nodo. Vacio, crear. Nodo(ivan, nodo. Vacio)) ABB = insertar. ABB(ivan, ABB) assert insertar. ABB(gustavo, ABB) == crear. Nodo(juan, crear. Nodo(gustavo, nodo. Vacio), crear. Nodo(ivan, nodo. Vacio, nodo. Vacio)) ABB = insertar. ABB(gustavo, ABB) # Error: tratar de insertar rut duplicado # assert insertar. ABB(gustavo, ABB) == crear. Nodo(juan, crear. Nodo( gustavo, nodo. Vacio), crear. Nodo(ivan, nodo. Vacio,

Borrar. ABB # borrar. ABB: int nodo -> nodo # devuelve ABB con los

Borrar. ABB # borrar. ABB: int nodo -> nodo # devuelve ABB con los valores en el ABB raiz pero #sin el nodo que contenga rut # ejemplo: con el ABB creado en tests anteriores # borrar. ABB(15, ABB) devuelve crear. Nodo(gustavo, #nodo. Vacio, crear. Nodo(ivan, nodo. Vacio)) def borrar. ABB(rut, raiz): # Caso base: borrar de un arbol vacio if raiz == nodo. Vacio: return nodo. Vacio

Borrar. ABB # Caso recursivo else: if rut < raiz. valor. rut: return crear.

Borrar. ABB # Caso recursivo else: if rut < raiz. valor. rut: return crear. Nodo(raiz. valor, borrar. ABB(rut, raiz. izq), raiz. der) elif rut > raiz. valor. rut: return crear. Nodo(raiz. valor, raiz. izq, borrar. ABB(rut, raiz. izq)) else: # rut == raiz. rut # Caso 1: borrar hoja if raiz. izq == nodo. Vacio and raiz. der == nodo. Vacio: return nodo. Vacio # Caso 2: borrar nodo con un solo hijo elif raiz. izq == nodo. Vacio: return raiz. der elif raiz. der == nodo. Vacio: return raiz. izq

Borrar. ABB- caso difícil # Caso 3: el caso dificil else: mayor = buscar.

Borrar. ABB- caso difícil # Caso 3: el caso dificil else: mayor = buscar. Mayor(raiz. izq) nueva. Izq = borrar. ABB(mayor. valor. rut, raiz. izq) return crear. Nodo(mayor. valor, nueva. Izq, raiz. der)

Buscar. Mayor # buscar. Mayor: nodo -> nodo # devuelve Nodo con el mayor

Buscar. Mayor # buscar. Mayor: nodo -> nodo # devuelve Nodo con el mayor valor de rut en el ABB raiz # ejemplo: # si ABB = crear. Nodo(15, "Juan", nodo. Vacio, crear. Nodo(24, "Ivan", #nodo. Vacio, nodo. Vacio)) # buscar. Mayor(ABB) devuelve crear. Nodo(24, "Ivan", nodo. Vacio, #nodo. Vacio) def buscar. Mayor(raiz): # pre-condicion: raiz no vacia assert raiz != nodo. Vacio # Caso base: nodo no tiene hijo derecho, es el mayor if raiz. der == nodo. Vacio: return raiz # Caso recursivo else: return buscar. Mayor(raiz. der)

Borrar. ABB - Tests # Test para borrar. ABB assert borrar. ABB(15, ABB) ==

Borrar. ABB - Tests # Test para borrar. ABB assert borrar. ABB(15, ABB) == crear. Nodo(gustavo, nodo. Vacio, crear. Nodo(ivan, nodo. Vacio))

Ordenar lista usando ABB • Supongamos que tenemos los datos de las personas en

Ordenar lista usando ABB • Supongamos que tenemos los datos de las personas en una lista. Queremos generar una nueva lista con los mismos datos de las personas, pero ordenados por RUT, de menor a mayor. • Este es un problema importante, y más adelante en el curso, veremos otras maneras de resolverlo. Ahora lo resolveremos con un ABB.

Ordenar lista por RUT from lista import * # ordenar. Lista: lista(personas) -> lista(personas

Ordenar lista por RUT from lista import * # ordenar. Lista: lista(personas) -> lista(personas # devuelve ordenada por rut la lista de personas una. Lista # ejemplo: ordenar. Lista(crear. Lista(persona(2, "a"), crear. Lista(persona(1, #"b“), lista. Vacia))) # devuelve crear. Lista(persona(1, "b"), crear. Lista(persona(2, "a"), lista. Vacia)) def ordenar. Lista(una. Lista): if vacia(una. Lista): return lista. Vacia else: arbol = insertar. Lista. En. ABB(una. Lista, crear. ABB()) return recorrer. ABBEn. Orden(arbol)

Insertar. Lista. En. ABB # insertar. Lista. En. ABB: lista(personas) nodo -> nodo #

Insertar. Lista. En. ABB # insertar. Lista. En. ABB: lista(personas) nodo -> nodo # devuelve ABB con las personas de una. Lista insertadas en raiz def insertar. Lista. En. ABB(una. Lista, raiz): if vacia(una. Lista): return raiz else: valor = cabeza(una. Lista) raiz = insertar. ABB(valor, raiz) return insertar. Lista. En. ABB(cola(una. Lista), raiz)

recorrer. ABBen. Orden # recorrer. ABBEn. Orden: nodo -> lista(personas) # devuelve la lista

recorrer. ABBen. Orden # recorrer. ABBEn. Orden: nodo -> lista(personas) # devuelve la lista de personas al recorrer el ABB en orden def recorrer. ABBEn. Orden(raiz): if raiz == nodo. Vacio: return lista. Vacia else: lista 1 = recorrer. ABBEn. Orden(raiz. izq) lista 2 = crear. Lista(raiz. valor, lista. Vacia) lista 3 = recorrer. ABBEn. Orden(raiz. der) return union. Listas(lista 1, union. Listas(lista 2, lista 3))

union. Listas # union. Listas: lista(any) -> lista(any) # devuelve lista resultado de unir

union. Listas # union. Listas: lista(any) -> lista(any) # devuelve lista resultado de unir dos listas # ejemplo: union. Listas(crear. Lista(1, lista. Vacia), crear. Lista(2, lista. Vacia)) #devuelve crear. Lista(1, crear. Lista(2, lista. Vacia)) def union. Listas(lista 1, lista 2): if vacia(lista 1): return lista 2 else: return crear. Lista(cabeza(lista 1), union. Listas(cola(lista 1), lista 2))

Test juan = persona(15, "Juan") ivan = persona(24, "Ivan") gustavo = persona (1, "Gustavo")

Test juan = persona(15, "Juan") ivan = persona(24, "Ivan") gustavo = persona (1, "Gustavo") maria = persona(7, "Maria") luisa = persona(9, "Luisa") francisca = persona (30, "Francisca") una. Lista = crear. Lista(juan, crear. Lista(ivan, crear. Lista(gustavo, crear. Lista(maria, crear. Lista(luisa, crear. Lista(francisca, lista. Vacia)))))) lista. Ordenada = ordenar. Lista(una. Lista) assert lista. Ordenada == crear. Lista(gustavo, crear. Lista(maria, crear. Lista(luisa, crear. Lista(juan, crear. Lista(ivan, crear. Lista(francisca, lista. Vacia)))))) #print una. Lista #print lista. Ordenada