Apo
Apo
Apo
Un rbol parcialmente ordenado (montculo) es un rbol completamente lleno, con la posible excepcin del nivel ms bajo, el cul se llena de izquierda a derecha (rbol completo).
3 9 15 17 19 25 21 28 30 10 35 40 6 16 37
Un rbol binario completo de altura h tiene entre 2h y 2h+1 -1 nodos. Esto implica que la altura de un rbol binario completo es log2 n, por lo que las inserciones y eliminaciones son O(log2 n).
Representacin de APO
3 9 6
6 15 21 10 16
15
21
10
16 17 19 25
17
19
25
maxNodos = 15
/* APO.h
*/ APO CrearAPO (int maxNodos); void InsertarAPO (tElemento e, APO A); void SuprimirMinAPO (APO A); tElemento RecuperarMinAPO (APO A); void DestruirAPO (APO A); int APOVacio (APO A); #endif
typedef char tElemento; /* Por ejemplo */ #ifndef _APO_ #define _APO_ typedef int nodo; /* ndice de la matriz entre 0 y maxNodos-1 */ typedef struct tArbol { tElemento *nodos; int maxNodos; int ultimo; } tipoArbol; typedef tipoArbol *APO;
*/
Insercin en un APO
Insertar 5 3 9 6
APO CrearAPO (int maxNodos) { APO A; A = (APO) malloc(sizeof(tipoArbol)); if (A == NULL) ERROR("CrearAPO(): No hay memoria"); A->nodos=(tElemento*) calloc(maxNodos, sizeof(tElemento)); if (A->nodos == NULL) ERROR("CrearAPO(): No hay memoria"); A->maxNodos = maxNodos; A->ultimo = -1; return A; }
15
21
10
16
17
19
25
Insercin en un APO
Insertar 5 9 3 6 Insertar 5
Insercin en un APO
3 6
15
10
16
15
10
16
17
19
25
21
17
19
25
21
Insercin en un APO
Insertar 5 5 3 6
void InsertarAPO (tElemento e, APO A) { nodo p; if (A->maxNodos - 1 == A->ultimo) ERROR("InsertarAPO(): APO lleno"); A->ultimo++; p = A->ultimo; while ((p > 0) && (A->nodos[(p-1)/2]>e)) { A->nodos[p] = A->nodos[(p-1)/2]; p = (p-1)/2; } A->nodos[p] = e; }
15
10
16
17
19
25
21
Suprimir en un APO
Caso 1 3 Caso 3 UltimoElto = 9
Suprimir en un APO
3
9 9
10
16
21
Suprimir en un APO
Caso 3 Caso 3
Suprimir en un APO
5
15
10
16
15
10
16
17
19
25
17
19
25
UltimoElto = 21
UltimoElto = 21
Suprimir en un APO
Caso 3 5 9 6 Caso 3
Suprimir en un APO
5 9 6
15
10
16
15
21
10
16
17
19
25
17
19
25
UltimoElto = 21
UltimoElto = 21
void SuprimirMinAPO (APO A) { nodo p, pMin; int fin; tElemento ultimoElto; if (A->ultimo == -1) ERROR("SuprimirAPO(): APO vaco"); ultimoElto = A->nodos[A->ultimo]; A->ultimo--; if (A->ultimo >= 0) { /* primer if*/ p = 0; if (A->ultimo > 0) { /*segundo if */ fin = 0;
}
while (p <= (A->ultimo-1)/2 && !fin) { if (2*p+1 == A->ultimo) pMin = 2*p+1; else if (A->nodos[2*p+1]<A->nodos[2*p+2]) pMin = 2*p+1; else pMin = 2*p+2; if (A->nodos[pMin] < ultimoElto) { A->nodos[p] = A->nodos[pMin]; p = pMin; } else fin = 1; } /* while */ } /* segundo if */ A->nodos[p] = ultimoElto; /* primer if */
tElemento RecuperarMinAPO (APO A) { return A->nodos[0]; } void DestruirAPO (APO A) { free(A->nodos); free(A); } int APOVacio (APO A) { return (A->ultimo == -1); }