Como inserir registros com chaves para uma árvore B + inicialmente vazia?

11

Mostre o resultado da inserção dos registros com as chaves na ordem (1, 2, 3, 4, 5) em uma árvore B + – inicialmente vazia da ordem m = 3. Em caso de estouro, divida o nó e não redistribua chaves para os vizinhos. É possível inserir os registros com chaves em uma ordem diferente para ter uma árvore com menos altura?

Em Relational DBMS Internals, capítulo 5: Organizações dinâmicas de estrutura em árvore, p.50

Ainda não sou bom nisso, tentei fazer ≤ à esquerda e> à direita:

Até inserção de 1,2:

insira a descrição da imagem aqui

Então, na medida em que temos que dividir o nó e não redistribuir as chaves para os vizinhos (eu o entendo como nós filhos), inseri apenas à direita da célula com 2:

insira a descrição da imagem aqui

E continuei fazendo o mesmo ao inserir 5:

insira a descrição da imagem aqui

Mas isso é muito estranho, nunca vi nós vazios como esses ... E não sei se ele respeita algumas propriedades muito básicas das árvores-B:

  • cada nó tem no máximo (m-1) chaves e pelo menos (⌈ (m / 2) ⌉-1) chaves, a menos que uma chave possa estar vazia e eu entenderia a chave como um "ponteiro".

Primeira tentativa: erro no pedido revelou uma árvore ambígua

No começo, eu não entendi o que era uma "ordem" (o número máximo de filhos por nó). Então, pensei que um nó pudesse ter três espaços (e, portanto, 4 filhos. Eu estava criando uma árvore de ordem 4, penso:

Até inserção de 1,2,3:

insira a descrição da imagem aqui

Inserção de 4, na medida em que precisamos dividir o nó e não redistribuir as chaves para os vizinhos (o que parece contraditório), eu deixaria 1,2,3 e 4,5 na folha direita após 3:

Árvore B da ordem 3 após inserir 4 e 5

Revolucion for Monica
fonte

Respostas:

6

Acho que você tem a criação da sua página de cabeça para baixo. Quando um nó é dividido, ele não cria mais nós na hierarquia (nós filhos na sua nomenclatura). Em vez disso, cria mais para cima , em direção à raiz. Como o livro diz

Observe que o crescimento está no topo da árvore, e essa é uma característica intrínseca de uma árvore B para garantir as propriedades importantes de que ela sempre tem todas as folhas no mesmo nível e que cada nó diferente da raiz é pelo menos 50% completo.

(Minha ênfase.)

No e-book vinculado:

Definição 5.1 AB - árvore da ordem m (m ≥ 3) ... cada nó contém no máximo m - 1 chaves

O exercício é para m = 3, portanto, no máximo 2 chaves por nó.

As duas primeiras chaves são fáceis - elas entram na primeira página:

A:[1,2]

Vou usar arte ASCII. Vou rotular cada página na sequência em que foram criadas e mostrar as chaves / ponteiros dentro da página. Portanto, a página P contendo os valores-chave k1 e k2 será P:[k1,k2].

Agora a chave 3 aparece. De acordo com a Seção 5.2.1 ... Inserção, a primeira tarefa é pesquisar. Isso determina que a chave 3 deve estar na página A - a única página que temos. Além disso "se [esse nó] estiver cheio, ele será dividido em dois nós". A página está cheia e deve ser dividida. Agora temos

A:[1,2]    B:[3, ]

Mas isso não é uma árvore! Como o livro diz:

o ponteiro para [o novo nó], .. é inserido no nó pai .. do [nó atual], repetindo a operação de inserção nesse nó [isto é, o nó pai]. Esse processo de divisão e movimentação pode continuar, se necessário, até a raiz e, se for necessário dividir, um novo nó raiz será criado.

(Minha ênfase em mostrar o processamento continua na árvore em direção à raiz, não nas folhas.)

Portanto, devemos colocar um ponteiro para a nova página (B) no pai da página atual (A). Deve haver um novo nó raiz:

      C:[2,3]
      /     \
A:[1,2]    B:[3, ]

Eu tenho os ponteiros em páginas que não são folhas, apontando para o valor mais alto em um nó filho (filho). Seu texto vinculado pode fazer isso de maneira diferente, mas o resultado será equivalente.

O valor-chave 4 chega; seguindo o algoritmo, procuramos encontrar em qual página ela deve estar. Deve ser a página B. Há espaço para isso; portanto, atualizamos essa página e o ponteiro na página C:

      C:[2,4]
      /     \
A:[1,2]    B:[3,4]

Em seguida, inserimos a chave 5. Ela deve aparecer na página B, mas está cheia. Portanto, divide

      C:[2,4]
      /     \
A:[1,2]    B:[3,4]   D:[5, ]

Nós devemos atualizar o nó pai. Ele também está cheio e se divide:

      C:[2,4]    E:[5, ]
      /     \         \
A:[1,2]    B:[3,4]   D:[5, ]

A divisão se propaga e um novo nó raiz se forma:

            F:[4,5]
            /     \
      C:[2,4]    E:[5, ]
      /     \         \
A:[1,2]    B:[3,4]   D:[5, ]

Ao crescer para cima, a árvore mantém uma profundidade idêntica em cada ramo. Isso é importante para o desempenho previsível. (Alguns dizem que o B na Árvore B significa "equilibrado" por essa mesma razão.)


Quanto à segunda parte - "É possível inserir os registros com chaves em uma ordem diferente para ter uma árvore de menor altura?" Com 5 chaves e duas chaves por nó, precisamos de pelo menos 3 nós de folha para armazenar todos os valores e uma altura de 3 para formar a árvore. Portanto, meu arranjo é ideal para os dados, sequência e algoritmo fornecidos.

O livro usa um arranjo de ponteiro muito diferente do que eu uso e um arranjo de divisão de página diferente. Isso será significativo, levando a páginas parcialmente cheias. O fato de haver uma seção na página 42 chamada "Carregamento de dados" que mostra como as páginas mais completas podem ser obtidas carregando a sequência de teclas suporta o meu palpite. No entanto, espero ter fornecido indicadores suficientes e você poderá usar a estrutura de indicadores do livro para resolver isso por si próprio.


Eu me deparei com esta simulação interativa de como uma B-Tree cresce.

Michael Green
fonte