560 likes | 775 Views
Estructura de Datos En C++. Dr. Romeo S ánchez Nigenda . E-mail: romeo.sanchez @ gmail.com http: //yalma.fime.uanl.mx/~ romeo / Oficina: 1er. Piso del CIDET. Oficina con Dr. Oscar Chacón Horas de Tutoría: 10am-11am Martes y Jueves, 3:30pm-4:30pm Miércoles, 2:00pm-4:00pm Viernes.
E N D
Estructura de Datos En C++ Dr. Romeo SánchezNigenda. E-mail: romeo.sanchez@gmail.com http://yalma.fime.uanl.mx/~romeo/ Oficina: 1er. Piso del CIDET. Oficina con Dr. Oscar Chacón Horas de Tutoría: 10am-11am Martes y Jueves, 3:30pm-4:30pm Miércoles, 2:00pm-4:00pm Viernes. Website: http://yalma.fime.uanl.mx/~romeo/ED/2011/ Sesiones: 48
Material de apoyo: Estructura de Datos con C y C++. YedidyahLangsam, Moshe J. Augenstein, Aaron M. Tenenbaum, Brooklyn College SegundaEdición, Prentice-Hall. Algorithms. ThirdEdition. Parts 1-4, Fundamentals Data StructuresSortingSearching Robert Sedgewick. Estructura de Datos. Román Martínez, Elda Quiroga. ThomsonLearning. Cualquier libro de Estructura de Datos! Software: Compiladores GCC (GNU CompilerCollection) IDEs (IntegratedDevelopmentEnvironment): http://www.eclipse.org/downloads/ http://kdevelop.org/ http://www.bloodshed.net/devcpp.html
6. Árboles • Objetivo: El alumno entenderá y aprenderá las estructuras de datos no lineales y dinámicas más importantes en computación. • Temario: • Árboles en general • Árboles binarios • Árboles balanceados • Árboles multicaminos
Árboles • En Informática, los árboles son abstracciones matemáticas que juegan un rol central en el diseño y análisis de algoritmos, porque: • Los usamos para describir propiedades dinámicas de los algoritmos • Construimos estructuras de datos que son realizaciones concretas de árboles. • Podemos concluir que un árbol es entonces una estructura de datos que mantiene un conjunto de nodos conectados (imitando la forma de un árbol). • Encontramos muchos ejemplos de árboles en nuestra vida diaria: • Organización de torneos deportivos • Árboles familiares (ascendientes y descendientes) • Organigramas de corporaciones • Procesamiento de lenguaje natural • Organización de sistemas de archivos (directorios y archivos)
Árboles • Existen diferentes tipos de árboles: • Árboles en general • Árboles binarios (AVL, Rojo-Negro, AA) • Árboles balanceados • Árboles multi-caminos (B, B+, B*) • En general un árboles un conjunto de vértices y aristas que satisfacen ciertos requisitos. • Un vértice es un objeto simple, también denominado nodo, que contiene información. • Una arista (o arco) es una conexión entre dos vértices • Un camino (o ruta) en un árbol es una lista de vértices distintos, en los que cada uno de ellos se encuentran conectados sucesivamente por aristas en el árbol. • La propiedad definitoria de un árbol es que existe solamente un camino o ruta conectando un par de nodos. Si hay más de un camino entre dos nodos, o si no hay un camino entre un par de nodos, entonces lo que tenemos es un Grafo.
Árboles: Terminología • Un nodo por lo tanto, es la unidad sobre la que se construye el árbol, y puede tener cero o más nodos hijos conectados a él (por medio de aristas) esta propiedad se le denomina grado. • Se dice que un nodo a es padre de un nodo b (o b es hijo de a) si existe un enlace desde ahasta b. • Un árbol solo puede tener un único nodo sin padres, al cual se le denomina raíz. En un árbol con raíz, cualquier nodo es la raíz de un subárbol, el cual consiste de sí mismo y de los nodos descendientes de él • Un nodo que no tiene hijos se le denomina hoja o terminal. • El resto de los nodos se les conoce como rama, ya que tienen padre y uno o varios hijos.
Árboles • En computación, usualmente se usa el término árbol para referirse a un árbol con raíz. Mientras que se asume el término árbol librepara referirse a la estructura más general. • Las aristas en un árbol no tienen dirección, usualmente se menciona que se encuentran apuntando hacia la raíz o fuera de ella. Y usualmente se coloca a la raíz en la cima del árbol. • Un árbol ordenado es un árbol con raíz en el cual el orden de los nodos descendientes (hijos) sigue un patrón determinado • Si cada nodo debe tener un número determinado de hijos en un orden específico, entonces tenemos un árbol de M-aristas. El árbol de M-aristas más simple es el árbol binario.
Árboles: Definición General • Caso base: Un árbol con un solo nodo, el cual es a la vez la raíz del árbol y una hoja. • Un árbol a partir de un nodo raíz R y k árboles A1, A2, A3,…, Akcon raíces n1, n2, n3, …, nkrespectivamente, y N1, N2, N3,…, Nk nodos cada uno. • El árbol resultante de N = 1 + N1 + N2 + N3 +…+Nknodos tiene como raíz al nodo R, por lo que los nodos n1, n2, n3, …, nkson los hijos de R. • A cada uno de los árboles Aise les denota como subárboles de la raíz. • Un recorrido es una sucesión de nodos del árbol de tal forma que entre cada dos nodos consecutivos de la sucesión hay una relación de parentesco.
Árboles: Definición General • Existen dos recorridos típicos para listar los nodos de un árbol: en profundidad y en anchura. • En profundidad (depth-first) listamos los nodos expandiendo primero el hijo actual de cada nodo hasta llegar a una hoja, al llegar a una hoja regresamos al nodo anterior probando el siguiente hijo, y así sucesivamente. • En anchura (breadth-first), antes de recorrer los nodos del nivel d+1 (profundidad de d+1 aristas desde la raíz), se listan todos los nodos del nivel d.
Árboles Binarios • Un árbol binarioes un conjunto finito de elementos que está vacío o dividido en tres subconjuntos: • El primer subconjunto contiene un elemento único, la raíz del árbol, • Un subárbol binario izquierdo que puede o no estar vacío • Un subárbol binario derecho equivalente al izquierdo • En otras palabras, un árbol binario es un nodo externo, o un nodo interno conectado a un par de árboles binarios, los subárboles izquierdo y derecho. raíz ancestro izq der descendiente hermanos hoja
Árboles Binarios Nivel = 0 • Nivel de un árbol binario: La raíz del árbol tiene el nivel 0, y el nivel de cualquier otro nodo en el árbol es uno más el nivel de su padre. Nivel = 1 Nivel = 2 Nivel = 3 Profundidad • Árbol binario completo: Es un árbol binario que tiene todos sus nodos completos en cada subárbol a una profundidad d. • Si un árbol binario contiene m nodos en el nivel l, entonces contiene un máximo de 2m nodos en el nivel l+1. Nivel = 0 1 Nivel = 1 2 nodos Nivel = 2 4 d 2lnodospornivel, por lo tanto la Cantidad de nodos en un árbol de Profundidad d es igual a la suma de Los nodos por nivel: N = 20 + 21 + … + 2d = ∑d 2j = 2d+1 - 1 j=0
Árboles Binarios: Operaciones • Entre las aplicaciones más comunes tenemos: • Dado un apuntador p a un nodo en un árbol binario Null info(p) : Retorna el contenido del nodo, en este ejemplo es a father(p) : Retorna un apuntador al padre del nodo p right(p) : Retorna un apuntador al hijo derecho del nodo left(p) : Retorna un apuntador al hijo izquierdo del nodo a isLeft(d) = true isLeft(e) = false isRight(g) = true b c d e f g brother(p) : Retorna un apuntador al hermano del nodo. Note que si no existe un nodo que satisfaga cualquiera de las funciones anteriores, se retorna un nulo (null) entonces. Las funciones lógicas isLeft(p) y isRight(p) retornan true si p se encuentra en el lado izquierdo o derecho de algún otro nodo respectivamente, false sino es el caso.
Árboles Binarios: Operaciones • Las funcionesisLeft(p), isRight(p), y brother(p), se implementanusando la funcionalidad de left(p), right(p), y father(p). Ejemplo: BoolisLeft(p) q = father(p) if(q == null) return false; if(left(q) == p) return true; return false; isLeft(a) ? a isLeft(c) ? isLeft(b) ? b c d e f g ImplementaisRight(p)!
Árboles Binarios: Operaciones father brother(p) if(father(p) == null) return null; if(isLeft(p)) return right(father(p)) return left(father(p)) brother(c) ? a b c d e f g • Operacionesadicionales: • makeTree(p) : Crea un árbol binario con un nodo único (raíz) • setLeft(p, x) : Establece un nodo x como hijo izquierdo de otro nodo p, • siempre y cuando p no tenga un hijo del lado izquierdo ya establecido. • - setRight(p, x) : Similar a la función anterior.
Árboles Binarios: Aplicación de Ejemplo • Los árboles binarios son útiles cuando se toman decisiones en dos sentidos en cada punto del proceso. • Ejemplo: Encontrar todos los duplicados en una lista de números: {15,4,8, 7, 4, 3, 19, 5, 7, 9, 16, 5,17} • Algoritmo: Primer elementoes la raíz, subsecuentes elementos se colocan a la izquierda si son menores o a la derecha si son mayores. Si son duplicados no se insertan pero se reportan. 15 15 15 15 15 4 4 4 4 4 8 8 3 8 7 7
Árboles Binarios: Aplicación de Ejemplo {15,4,8, 7, 4, 3, 19, 5, 7, 9, 16, 5,17} 15 15 15 4 19 4 19 4 19 3 3 3 16 8 8 8 7 9 17 7 7 … 5 5
Árboles Binarios: Aplicación de Ejemplo Pseudocódigo: intnumbers[13] = {15,4,8, 7, 4, 3, 19, 5, 7, 9, 16, 5,17}; tree = makeTree(numbers[0]); for(inti=1;i<length(numbers);i++){ p = q = tree; while(numbers[i] !=info(p) && q!=NULL){ p = q; if(numbers[i]<info(p)) q = left(p); else q = right(p); } if(numbers[i] == info(p)) cout<<“Numerorepetido”; else if(numbers[i] < info(p)) setleft(p,numbers[i]); else setright(p, numbers[i]); } 15 4 19 3 16 8 9 17 7 5
Ejemplo 2: Expresiones • La raíz del árbol binario contiene un operadorque se aplicará a la evaluación de las expresiones representadas por sus subárboles izquierdo y derecho. • Los operandos son únicamente hojas en el árbol + $ A * + * A+B*C B C A + * C * C B B A + C (A+B*C)$((A+B)*C) A B (A+B)*C
Representación básica de un árbol binario structtnode { intinfo; structtnode * father; //No necesario structtnode * left; structtnode * right; }; typedefstructtnode * TNODEPTR; TNODEPTRcreateNode() { TNODEPTR p = (TNODEPTR) malloc(sizeof(structtnode)); return p; } voidfreeNode(TNODEPTR P) { free( p); } p
Representación básica de un árbol binario TNODEPTRmakeTree(int x) { TNODEPTR root = createNode(); root->info = x; root->father = NULL; root->left = NULL; root->right = NULL; return root; } TNODEPTRfather(TNODEPTRpNode) { returnpNode->father; } TNODEPTRleftChild(TNODEPTRpNode) { returnpNode->left; } TNODEPTRrightChild(TNODEPTRpNode) { returnpNode->right; }
Representación básica de un árbol binario voidsetLeftChild(TNODEPTRpNode, int x) { if (pNode == NULL) cout << "Error, padre es nulo!" << endl; elseif (leftChild(pNode) != NULL) cout << "Error, hijo izquierdo presente!“;else { pNode ->left = makeTree(x); pNode ->left ->father = pNode; } } pNode pNode pNode makeTree(x); pNode->left=… pNode ->left ->father = pNode; voidsetRightChild(TNODEPTRpNode, int x){…} //Es similar
Representación básica de un árbol binario boolisLeft(TNODEPTRpNode) { if (pNode == NULL) returnfalse; elseif (father(pNode) == NULL) returnfalse; else return (leftChild(father(pNode)) == pNode); } boolisRight(TNODEPTRpNode) { if (pNode == NULL) returnfalse; elseif (father(pNode) == NULL) returnfalse; return (rightChild(father(pNode)) == pNode); }
Representación básica de un árbol binario TNODEPTRsibling(TNODEPTRpNode) { if (pNode == NULL) return NULL; if (father(pNode) == NULL) return NULL; if (isLeft(pNode)) returnrightChild(father(pNode)); else returnleftChild(father(pNode)); } a father b c d e f g sibling(c) ?
Árbol binario de búsqueda u ordenado • El ejemplo anterior introdujo el árbol binario de búsqueda o árbol binario ordenado • Este tipo de árbol tiene todos sus nodos en orden, para cada nodo X: • Todos los elementos de su árbol izquierdo son menores o iguales a X, • Mientras los nodos en su árbol derecho son mayores a X. • En promedio, un árbol binario ordenado puede localizar un nodo en un árbol de N nodos en tiempo log(N).
Búsqueda en un árbol binario ordenado 15 //Dado un árbol binario, retorna //verdaderosi el datobuscado se //encuentra en el árbol, o falso si no bool find(TNODEPTRpNode, int data){ //Casobase:arbolvacio if(pNode==NULL){ return false; } else{ //Datoesencontrado if(pNode->info==data){ return true; }else{ if(data<pNode->info){ //Recursa a la izqsiesmenor return find(pNode->left,data); } else{ //Recursa a la derechasies mayor return find(pNode->right,data); } } } } 4 19 3 16 8 9 17 7 5
Inserción en un árbol binario ordenado 15 4 19 //Dado un árbol binario, inserta un //nuevonodo en el lugarcorrecto del arbol. TNODEPTR insert(TNODEPTRpNode, int data){ //1: Si el arbolestavacioretorna //un nodounico if(pNode==NULL){ return makeTree(data); } else{ //Recursahaciaabajo del arbol //Para encontrar el lugarcorrecto if(data<=pNode->info){ pNode->left = insert(pNode->left, data); }else{ pNode->right = insert(pNode->right, data); } //Retorna el nodo original sin cambiar return(pNode); } } 3 16 8 1 9 17 7 5
Árbol binarios: Ejercicio simple • Escribe código que implemente el siguiente árbol binario: 2 • Llamando a makeTree tres veces • y usandotres variables puntero. TNODEPTR build123(){ TNODEPTR one, two three; one = makeTree(1); two = makeTree(2); three = makeTree(3); two->left = one; two->right = three; return two } 1 3 • Llamando a makeTree tres veces • y usandouna variable puntero. TNODEPTR build123(){ TNODEPTR two; two = makeTree(2); two->left = makeTree(1); two->right = makeTree(3); return two } • Llamando a insert tres veces, • pasándole la raíz del árbol. TNODEPTR build123(){ TNODEPTR root=NULL; root = insert(root,2); root = insert(root,1); root = insert(root,3); return root; }
Árbol binarios: Ejercicio simple • Implementa la funciónsizeque calcula el número de nodos en un árbol binario. intsize(TNODEPTRpNode){ if(pNode==NULL){ return 0; }else{ return (size(pNode->left)+ 1 + size(pNode->right)); } } • Dado un árbol binario ordenado no nulo, implementa una función que retorne el valor mínimo en el árbol intminimum(TNODEPTRpNode){ TNODEPTR current = pNode; while(current->left!=NULL) current = current->left } return current->info; }
Recorrido de árboles binarios • Recorrer un árbol binario significa visitar la raíz y recorrer sus subárboles izquierdo y derecho de forma recursiva. • Orden previo: • Visitar la raíz • Recorrer el subárbol izquierdo en orden previo • Recorrer el subárbol derecho en orden previo voidrecorridoPreorden(TNODEPTRpNode){ if(pNode!=NULL){ cout<<"Node: "<<pNode->info; recorridoPreorden(pNode->left); recorridoPreorden(pNode->right); } } A 1 B C 2 5 D E 3 F 6 ABDGCEHIF 9 H I G 4 7 8
Recorrido de árboles binarios • Orden Simétrico/Inorden: • Recorrer el subárbol izquierdo en orden simétrico • Recorrer la raíz • Recorrer el subárbol derecho en orden simétrico voidrecorridoInorden(TNODEPTRpNode){ if(pNode!=NULL){ recorridoPreorden(pNode->left); cout<<"Node: "<<pNode->info; recorridoPreorden(pNode->right); } } A 4 B C 3 8 DGBAHEICF D E 1 F 6 9 H I G 2 5 7
Recorrido de árboles binarios • Orden Posterior: • Recorrer el subárbol izquierdo en orden posterior • Recorrer el subárbol derecho en orden posterior • Recorrer la raíz voidrecorridoPostorden(TNODEPTRpNode){ if(pNode!=NULL){ recorridoPreorden(pNode->left); recorridoPreorden(pNode->right); cout<<"Node: "<<pNode->info; } } A 9 B C 3 8 GDBHIEFCA D E 2 F 6 7 H I G 1 4 5
Remoción en un árbol binario ordenado 15 15 15 15 • Se presentan tres casos: • El nodo a suprimir no tiene hijos: Se elimina el nodo del árbol sin mayores ajustes • Si el nodo a suprimir sólo tiene un subárbol: Su único hijo se mueve hacia arriba y ocupa su lugar • El nodo a suprimir tiene dos subárboles: Su sucesor de orden intermedio S (o antecesor) debe ocupar su lugar. Elsucesor intermedio es el nodo hijo más a la izquierda en su árbol derecho. Dicho nodo no puede tener un subárbol izquierdo. El antecesor sería el nodo hijo más a la derecha de su árbol izquierdo. 4 4 4 8 19 19 19 19 3 16 16 16 16 8 8 8 15 4 23 19 3 8 16 25 18 23 24 24
Remoción en un árbol binario ordenado 15 15 15 15 voiddeleteNode(TNODEPTR tree, int x) { TNODEPTR p = tree, q = NULL, rp; while (p != NULL && p->info != x) { q = p; p = (x < p->info) ? p->left : p-> right; } if (p == NULL) return; if (p->left == NULL) rp = p-> right; elseif (p-> right == NULL) rp = p->left; else { TNODEPTR f = p; rp = p-> right; TNODEPTR s = rp->left; while (s != NULL) { f = rp; rp = s; s = rp->left; } if (f != p) { f->left = rp->right; rp->right = p->right; } rp->left = p->left; } if (q == NULL) tree = rp; else (p == q->left) ? q->left = rp : q->right = rp; freeNode(p); } 4 4 4 8 19 19 19 19 3 16 16 16 16 8 8 8 15 4 23 19 3 8 16 25 18 23 24 24
Árboles Balanceados • La altura (profundidad) de un árbol binario es el nivel máximo de sus hojas • Un árbol binario balanceado o árbol AVL es aquel en el que las alturas de los dos subárboles de cada nodo nunca difieren en más de 1. • El balance de un nodo en un árbol binario se define como la altura de su subárbol izquierdo menos la altura de su subárbol derecho. • Por lo tanto, cada nodo en un árbol AVL tiene un balance de 1, -1 o 0, dependiendo de si la altura de su subárbol izquierdo es mayor que, menor que o igual a la altura del derecho.
Árboles Balanceados -1 0 1 -1 0 1 0 0 0 0 0 0 0 0 0 0 0 Factor de Equilibrio (FE): Cada nodo en un árbol AVL tiene un balance de 1, -1 o 0, dependiendo de si la altura de su subárbol izquierdo es mayor que, menor que o igual a la altura del derecho. Si el FE>=2, esnecesarioreequilibrar el árbol.
Árbol AVL • Debido a que los árboles están balanceados, la complejidad de búsqueda de un elemento es del orden O(log n). • Las operaciones en un árbol AVL balanceado son las mismas que en un árbol binario de búsqueda desequilibrado, pero si al insertar o borrar elementos el árbol pierde su balance entonces se rotan los nodos para equilibrar de nuevo el árbol. • El propósito de la rotación es que el recorrido de orden intermedio del árbol rotado sea el mismo que para el árbol original (es decir, el árbol rotado sigue siendo un árbol de búsqueda binaria).
Árbol AVL: Representación Cada nodo debe contener, además de los datos, su factor de equilibrio y los punteros hacia sus hijos. Por ejemplo: P = {data=10, left=7, right=15, FE=2} p 10 7 15 5 8 2 6
Árbol AVL: Rotaciones 7 2,5,6,7,8,10,15 5 10 15 2 8 6 10 5 2 7 7 15 2,5,6,7,8,10,15 6 10 5 8 Recorrido Inorder 15 8 2 6 Rotación derecha Rotación izquierda
Algoritmo de Rotación Izquierda r q = right(p); temp = left(q); left(q) = p; right(p) = temp 7 p r’ p 5 10 15 r l l lr’ 2 8 6 lr’ r’ 10 7 15 Rotación izquierda 5 8 Dado un árbol de raíz p, y de hijo izquierdo l y derecho r, se forma un nuevo árbol cuya raíz sea la raíz del hijo del lado derecho (es decir r), y como su hijo derecho le colocamos el hijo derecho que tenía anteriormente (es decir r’). Del lado izquierdo de la nueva raíz r, colocamos a la raíz anterior p, teniendo como raíz de su subárbol derecho el hijo izquierdo lr’ de la nueva raíz r’. 2 6
RotacionesDobles r Si la inserción se produce en el hijo derecho (lr’) del hijo izquierdo (p) del nodo desequilibrado (r) o viceversa , se realizará una doble rotación. Rotación Doble a la Derecha: Primero es una rotación simple a la izquierda, y luego rotación simple a la derecha. r’ p l lr’ 8 10 12 12 Rotación a la izquierda Rotación a la derecha 9 7 15 9 15 7 12 7 10 5 9 8 5 10 15 5 8 2 6 2 6 2 6
Casos de Inserción • La inserción funciona como si fuera un árbol de búsqueda binario desequilibrado, retrocediendo hacia la raíz y rotando sobre cualquier nodo no balanceado. Nuevo nodo Solución: Rotación Derecha Caso 1: Izquierda * Imágenes tomadas de Wikimedia bajo licencia de documentación libre GNU
Casos de Inserción • Caso 2: Derecha Nuevo nodo Solución: Rotación Izquierda * Imágenes tomadas de Wikimedia bajo licencia de documentación libre GNU
Casos de Inserción • Caso 3: Izquierda-Derecha Solución: Rotación doble Rotación Izquierda Rotación Derecha * Imágenes tomadas de Wikimedia bajo licencia de documentación libre GNU
Casos de Inserción • Caso 4: Derecha-Izquierda Solución: Rotación doble Rotación Derecha Rotación Izquierda * Imágenes tomadas de Wikimedia bajo licencia de documentación libre GNU
Árboles Multicaminos • Un árbol multi-camino o multi-direccional de orden n, es un árbol general en el cual cada nodo tiene n o menos subárboles, y contiene una llave (key) menos que subárboles. • Sea A un árbol de n-caminos si y solo si: • A está vacío • A puede tener hasta n subárbolesS0, S1, S2, …, Sn-1 en cada nodo • Dado n subárboles para un nodo p de A;p tiene Kn-2 llaves en orden. Es decir, cada nodo contiene una llave menos que subárboles • Todas las llaves en el subárbol S0 son menores que o iguales a K0, mientras todas las llaves en los subárbolesSj (1<j<n-2) son mayores que Kj-1. • Todas las llaves en el subárbol Sn-1 son mayores que las llaves kn-2.
Árboles Multicaminos: Nodos Nodo A Cantidad variable de apuntadores Cantidad variable de llaves X X X X < K0 Kj-1 < X < Kj X > Kn-2
Árboles Multicaminos: Ejemplos Árbol multicamino de orden 4. 12 50 85 Máxima cantidad de llaves es 3 A 60 70 80 100 120 150 6 10 37 B C D E 25 62 65 69 110 H F G
Árboles Multicaminos: Operaciones Básicas 12 50 85 • numTrees(p): Dado un nodo multicaminop, retorna el número de hijos (subárboles) de p (0<=numTrees(p)<=n). Donde n es el orden o grado del árbol. • child(p,i): Retorna el i_ésimo hijo del nodo p. Donde 0<=i<numTrees(p)-1. • key(p,j): Retorna la j_ésima llave del nodo p. Donde 0<=j<numTrees(p)-2 son lasllaves en ordenascendente A 60 70 80 100 120 150 6 10 37 numTrees(A) => 4 B C D E key(A,2) key(A,0) child(A,3) child(A,0)
Árboles Multicaminos: Operaciones Básicas child(p,i) para 1<=i<=numTrees(p)-2, contienetodaslasllavesen el árbol entre key(p, i-1) y key(p,i). 12 50 85 A child(p, numTrees(p)-1) apunta a un subárbol que contiene únicamente llaves mayores a key(p, numTrees(p)-2). key(A,0) key(A,2) child(p,0) apunta a un subárbol cuyas llaves son todas menores que la llave key(p,0). 60 70 80 100 120 150 6 10 37 B C D E child(A,3): Las llaves de estenodo: {100,120, 150} > 85 child(A,0): Las llaves de este nodo {6,10} < 12