Sei sulla pagina 1di 7

rboles B

B-rboles son rboles equilibrados diseados para trabajar con dispositivos de almacenamiento secundario, como discos magnticos. Su objetivo es optimizar las operaciones en los dispositivos de entrada y salida. Tiempo de acceso a la informacin en un disco se daa principalmente por el brazo de posicionamiento lectura tiempo. Una vez que el brazo se coloca en la ubicacin correcta, la lectura se puede realizar con bastante rapidez. Por lo tanto, se minimiza el nmero de accesos a disco. A diferencia de los rboles binarios, cada nodo en un rbol B puede tener muchos hijos, es decir, el grado de un nodo puede ser muy grande. Definicin: Un rbol B tiene las siguientes propiedades: 1. Cada nodo X tiene los siguientes campos: a. n , el nmero de claves almacenadas en X ; b. las n claves k 1 , k 2 ... k n se almacenan en orden ascendente; c. hoja , que indica si X es una hoja o un nodo interno. 2. Si X es un nodo interno, entonces tiene n +1 punteros f 1 , f 2 ... f n +1 para sus hijos (y algunos pueden ser null) 3. Si k i es algo clave en el subrbol apuntado por f i , a continuacin, 4. Todas las hojas del rbol son al mismo tiempo (que es la altura del rbol). 5. Hay un nmero mnimo y mximo de los nios en un nodo. Este nmero puede ser descrito en trminos de un fijo de enteros t mayores que o igual a 2 llamado el grado mnimo . a. Todos excepto el nodo raz debe tener al menos t-1 llaves. Todo nodo interno que no sea el root debe tener al menos t hijos. Si el rbol no est vaco, entonces la raz tiene al menos una clave. b. Cada nodo puede contener como mximo 2t - 1 llaves. Pronto un nodo interno puede tener en la mayora de 2t nios. Se dice que un nodo es completa si contiene 2t - 1 llaves.
const t = 2; typedef struct no_arvoreB arvoreB; struct no_arvoreB { int num_chaves; carbn teclas [2 * t-1]; arvoreB nios * [2 * t]; bool hojas; };

Estructura Nodo

De acuerdo con la definicin anterior B-tree sencillo es cuando t = 2 . En este caso, cualquier nodo que no sea la raz tiene 2, 3 o 4 hijos. Este rbol es tambin conocido como 2-3-4 rbol .

B-rbol con t = 2

Decimos que B es un rbol de orden n , donde n es el nmero mximo de hijos de un nodo, excepto la raz. Por ejemplo, un rbol B de orden 4 puede tener un mximo de ocho y un mnimo de cuatro nios en cada nodo. Sin embargo, la palabra "orden" se utiliza de diferentes maneras por los autores puede indicar el nmero mximo de claves en cada nodo, o incluso la ocupacin mnima en cada nodo. Altura del rbol El nmero de accesos requeridos para las operaciones en un rbol B es proporcional a la altura del rbol. Teorema: Un rbol B con n llaves, altura h y el grado mnimo t> = 2 satisface la relacin:

Prueba: Si un rbol B tiene una altura h , se reduce al mnimo el nmero de nodos cuando la raz contiene una clave y todos los otros nodos contienen t 1 teclas. En este caso, hay dos nodos en el nivel 1, 2 t nodos en el nivel 2, 2 t

nodos en el nivel 3, y la altura h tiene 2 t h-1 nodos. Por lo tanto, el nmero de teclas satisface

La insercin en un rbol B Para insertar un nuevo elemento en un rbol B, slo tiene que localizar el nodo hoja X , donde se debe insertar el nuevo elemento. Si el nodo X est lleno, debe realizar una subdivisin consistente de nosotros pasamos el elemento mediana de X de su padre y de divisin X en dos nuevos nodos con t - 1 elementos y luego inserte la nueva llave.

Pasos para insertar la llave 80 en un rbol B con t = 2

Si el padre de X tambin est lleno, que se repite recursivamente subdividir Hasta los padres X . En el peor de los casos tendr que aumentar la altura del rbol B con el fin de insertar el nuevo elemento. Tenga en cuenta que a diferencia de los rboles binarios, rboles B crecen. La siguiente figura ilustra la inclusin de nuevos elementos en un rbol B en t = 3 .

Algoritmo para insero em uma rvore B


const T = 2, MAX_CHAVES = 2 * T - 1, //Quantidade mxima de chaves MAX_FILHOS = 2 * T, //Quantidade mxima de filhos MIN_OCUP = T - 1; //Ocupao mnima em cada n typedef struct no_arvoreB arvoreB; struct no_arvoreB { int num_chaves; //Quantidades de chaves contida no n int chaves[MAX_CHAVES]; //Chaves armazenadas no n arvoreB *filhos[MAX_FILHOS]; //Ponteiro para os filhos }; //Insere uma chave e o ponteiro para o filho da direita em um n void insere_chave(arvoreB *raiz, int info, arvoreB *filhodir) {

int k, pos; //busca para obter a posio ideal para inserir a nova chave pos = busca_binaria(raiz, info); k = raiz->num_chaves; //realiza o remanejamento para manter as chaves ordenadas while (k > pos && info < raiz->chaves[k-1]) { raiz->chaves[k] = raiz->chaves[k-1]; raiz->filhos[k+1] = raiz->filhos[k]; k--; } //insere a chave na posio ideal raiz->chaves[pos] = info; raiz->filhos[pos+1] = filhodir; raiz->num_chaves++; } //Realiza a busca do n para inserir a chave e faz as subdivises quando necessrias arvoreB *insere(arvoreB *raiz, int info, bool *h, int *info_retorno) { int i, j, pos, info_mediano; //auxiliar para armazenar a chave que ir subir para o pai arvoreB *temp, *filho_dir; //ponteiro para o filho direita da chave if (raiz == NULL) { //O n anterior o ideal para inserir a nova chave (chegou em um n folha) *h = true; *info_retorno = info; return(NULL); } else { pos = busca_binaria(raiz,info); if (raiz->num_chaves > pos && raiz->chaves[pos] == info) { printf("Chave j contida na rvore"); *h = false; } else { //desce na rvore at encontrar o n folha para inserir a chave. filho_dir = insere(raiz->filhos[pos],info,h,info_retorno); if (*h) //Se true deve inserir a info_retorno no n. { if (raiz->num_chaves < MAX_CHAVES) //Tem espao na pgina { insere_chave(raiz, *info_retorno, filho_dir); *h = false; }

else { //Overflow. Precisa subdividir temp = (arvoreB *) malloc (sizeof(arvoreB)); temp->num_chaves = 0; //inicializa filhos com NULL for (i = 0; i < MAX_FILHOS; i++) temp->filhos[i] = NULL; //elemento mediano que vai subir para o pai info_mediano = raiz->chaves[MIN_OCUP]; //insere metade do n raiz no temp (efetua subdiviso) temp->filhos[0] = raiz->filhos[MIN_OCUP+1]; for (i = MIN_OCUP + 1; i < MAX_CHAVES; i++) insere_chave(temp, raiz->chaves[i], raiz>filhos[i+1]); //atualiza n raiz. for (i = MIN_OCUP; i<MAX_CHAVES; i++) { raiz->chaves[i] = 0; raiz->filhos[i+1] = NULL; } raiz->num_chaves = MIN_OCUP; //Verifica em qual n ser inserida a nova chave if (pos <= MIN_OCUP) insere_chave(raiz, *info_retorno, filho_dir); else insere_chave(temp, *info_retorno, filho_dir); //retorna o mediano para inser-lo no n pai e o temp como filho direito do mediano. *info_retorno = info_mediano; return(temp); } } } } } arvoreB *insere_arvoreB(arvoreB *raiz, int info) { bool h; int info_retorno, i; arvoreB *filho_dir, *nova_raiz; filho_dir = insere(raiz,info,&h,&info_retorno); if (h) { //Aumetar a altura da rvore nova_raiz = (arvoreB *) malloc (sizeof(arvoreB)); nova_raiz->num_chaves = 1; nova_raiz->chaves[0] = info_retorno;

nova_raiz->filhos[0] = raiz; nova_raiz->filhos[1] = filho_dir; for (i = 2; i <= MAX_CHAVES; i++) nova_raiz->filhos[i] = NULL; return(nova_raiz); } else return(raiz); }

Potrebbero piacerti anche