Universidade Católica de Goiás Departamento de Computação Estrutura de Dados I Prof. Alexandre Ribeiro Quarto Trabalho – 1º sem de 2007 Objetivo: 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. Implementação: Descrição de um nó 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 Folha; /* valor lógico que indica se o nó é folha ou não */ 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 */ int* Pos; /* Posição da página dentro do arquivo em bytes a partir do início*/ }; Exemplos (ordem 2 ou t=3) Raiz com um único elemento. Raiz com o número máximo de elementos Árvore com três nós: 1. 2. 3. 4. 5. 6. 7. 8. 9. Funções a serem implementadas 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 (descritor 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.