A map
реализовано с использованием бинарного дерева поиска.Чтобы соответствовать требованиям сложности, это должно быть самобалансирующееся дерево, поэтому обычно используется красно-черное дерево, но это не влияет на то, как вы выполняете итерацию по дереву.
Чтобы прочитать элементы избинарное дерево поиска по порядку от наименьшего к наибольшему, вам нужно выполнить обход дерева по порядку.Рекурсивная реализация довольно проста, но не очень практична для использования в итераторе (итератору придется поддерживать стек внутри, что делает его копирование относительно дорогим).
Вы можете реализовать итерацию впорядок обходаЭто реализация, взятая из библиотеки контейнеров дерева, которую я написал некоторое время назад.NodePointerT
- указатель на узел, где узел имеет указатели left_
, right_
и parent_
типа NodePointerT
.
// Gets the next node in an in-order traversal of the tree; returns null
// when the in-order traversal has ended
template <typename NodePointerT>
NodePointerT next_inorder_node(NodePointerT n)
{
if (!n) { return n; }
// If the node has a right child, we traverse the link to that child
// then traverse as far to the left as we can:
if (n->right_)
{
n = n->right_;
while (n->left_) { n = n->left_; }
}
// If the node is the left node of its parent, the next node is its
// parent node:
else if (n->parent_ && n == n->parent_->left_)
{
n = n->parent_;
}
// Otherwise, this node is the furthest right in its subtree; we
// traverse up through its parents until we find a parent that was a
// left child of a node. The next node is that node's parent. If
// we have reached the end, this will set node to null:
else
{
while (n->parent_ && n == n->parent_->right_) { n = n->parent_; }
n = n->parent_;
}
return n;
}
Чтобы найти первый узел для begin
итератор, вам нужно найти самый левый узел в дереве.Начиная с корневого узла, следуйте указателю левого потомка, пока не встретите узел, у которого нет левого потомка: это первый узел.
Для итератора end
вы можете установить указатель узла так, чтобы он указывал на корневой узел или на последний узел дерева, а затем оставить флаг в итераторе, указывающий, что это конечный итератор (is_end_
или что-то подобное).