Мы можем создать B-дерево за один проход, но это может быть не самый оптимальный способ хранения. В зависимости от того, как часто вы делаете последовательные запросы против запросов с произвольным доступом, может быть лучше хранить их в последовательности и использовать двоичный поиск для обслуживания запроса произвольного доступа.
Тем не менее, предположим, что каждая запись в вашем b-дереве содержит (m - 1) ключей ( m > 2, двоичный регистр немного отличается). Мы хотим, чтобы все листья на одном уровне и все внутренние узлы имели как минимум ключи (m - 1) / 2 . Мы знаем, что полное b-дерево высотой k имеет (m ^ k - 1) ключей. Предположим, что у нас есть n ключей для хранения. Пусть k будет наименьшим целым числом таким, что m ^ k - 1> n . Теперь, если 2 m ^ (k - 1) - 1 , мы можем полностью заполнить внутренние узлы и равномерно распределить оставшиеся ключи по листовым узлам, причем каждый листовой узел получает либо слово, либо потолок (n + 1 - m ^ (k - 1)) / m ^ (k - 1) ключей. Если мы не можем этого сделать, то мы знаем, что у нас достаточно, чтобы заполнить все узлы на глубине k - 1 хотя бы наполовину и сохранить один ключ в каждом из листьев.
Как только мы определились с формой нашего дерева, нам нужно только выполнить обход по порядку дерева, последовательно сбрасывая ключи в нужное положение.