O objetivo deste laboratório é a implementação das rotinas de manipulação de dados em disco para árvores B, considerando tanto a inserção quanto a remoção de dados. Você poderá se basear nas funções abaixo apresentadas ou fazer outra implementação.
A declaração abaixo permite que a ordem da árvore seja escolhida em tempo de execução. Cada nó, poderá ter no mínimo ord e no máximo 2 * ord chaves. Os vetores de chaves e apontadores serão alocados dinamicamente de acordo com a ordem da árvore. Uma posição a mais pode ser alocada para facilitar a implementação da operação de inserção. Além disso cada um dos nós possuirá um identificador único que permitirá a definição da quantidade de bytes que será percorrida desde o início do arquivo para achar os dados de um nó filho.
typedef struct no* ap_no;
typedef struct arv_B Arv_B;
struct arv_B {
ap_no m_pRoot; /* Apontador para a árvore propriamente dita */
int m_nOrd; /* Ordem da árvore */
int m_nNumPages; /* Número de páginas na árvore */
};
struct no {
int m_nIndex; /* Índice do nó */
int m_nSize; /* Número de chaves válidas no nó */
int* m_pKeys; /* Endereço inicial do vetor de chaves */
ap_no* m_pChildren; /* Endereço inicial do vetor de apontadores para os nós filhos */
}; Raiz com um único elemento.
Raiz com o número máximo de elementos
Árvore com três nós:
void inicia_arvore(Arv_B *t, int ord);
Inicia uma árvore B de ordem ord. O primeiro nó a ser armazenado no arquivo será utilizado para armazenar informações gerais da árvore.
void escreve(Arv_B t);
Escreve os elementos de t em ordem crescente. Deixa uma linha em branco caso t esteja vazia.
int insere(Arv_B *t, int v);
Insere a chave v na árvore t; retorna 1 caso a inserção tenha sido bem sucedida ou 0 caso a chave já esteja presente na árvore.
void insere_disco(Arv_B *t, int pos, ap_no no, char * fileName);
Insere o nó no na árvore t na posição pos do arquivo fileName .
int busca(Arv_B t, int ch, int &pos);
Verifica a existência da chave ch na árvore t (retornando falso ou verdadeiro). A variável pos retorna a posição do nó no qual a chave se encontra.
void le_disco(Arv_B *t, int pos, ap_no no, char * fileName);
Dada uma posição pos no arquivo fileName , carregue esses dados na variável no.
int deleta(Arv_B *t, int v);
Deleta a chave v na árvore t; retorna 1 caso a deleção tenha sido bem sucedida ou 0 caso a chave já esteja presente na árvore.
void deleta_disco(Arv_B *t, int pos, ap_no no, char * fileName);
Deleta o nó no da árvore t que se encontra na posição pos no arquivo fileName .
int libera (Arv_B *t);
Desaloca a memória de todos os nós de t.
A interface que trabalha sobre uma árvore t deve conter as seguintes operações:
i v
Insere a chave v na árvore t
d v
Deleta a chave v na árvore t
b v
Verifica se a chave v está presente na árvore t
e
Escreve os elementos da árvore t em ordem crescente.
l
Libera os nós da árvore t a reinicializa com NULL.
i 3 i 2 i 1 i 6 e 1 2 3 6 i 4 e 3 1 2 4 6 d 1 1: chave deletada. e 3 2 4 6 b 4 4: chave encontrada. l b 4 4: chave não encontrada. e