struct BTreeNode {
    bool is_leaf=true;
    std::vector<int> elements;
    std::vector<BTreeNode*> children;
    BTreeNode() {}
    BTreeNode (std::vector<int> v) {
    this->elements = v;
    }
};

void traverse(BTreeNode* root) {
  for(int i = 0; i < (int)root->children.size(); ++i){
    traverse(root->children[i]);
    cout << root->elements[i] << endl;
  }
  traverse(root->children[root->children.size() -1]);
}

Мой метод как-то segfaults. Как мы пишем правильный InOrder Traversal для B-Tree?

2
user7607599 31 Мар 2017 в 00:25

2 ответа

Лучший ответ

Вероятно, это последний траверс, когда вы находитесь на листе. Я не думаю, что этот ход нужен.

1
Mike 30 Мар 2017 в 21:38

Предполагая, что BTreeNode - это общее определение вашего узла b-дерева, тогда как T1 - это тип ключей, а T2 - это тип значений в дереве, а sortedKeys - это список, за которым вы следите, вы можете использовать следующий рекурсивный метод. Идея очень похожа на обход inOrder в дереве бинарного поиска: сначала зайдите к самому левому дочернему элементу, затем к ключу, а затем продолжите, так как число дочерних элементов в B-дереве всегда на единицу больше, чем количество ключей, проверка необходима перед посещением ключа [код написан на c #, но может быть легко преобразован в любой другой язык, целью является показать только алгоритм].

public void InOrderTraversal(BTreeNode<T1, T2> node, List<KeyValuePair<T1, T2>> sortedKeys)
        {
            if (node != null)
            {
                for (int i = 0; i < node.Children.Count; i++)
                {
                    InOrderTraversal(node.Children[i], sortedKeys);
                    if (i < node.KeyValues.Count)
                        sortedKeys.Add(node.KeyValues[i]);
                }
            }
        }
0
PiJei 21 Мар 2019 в 09:23