Мне нужно найти преемника по порядку в бинарном дереве поиска. Например, дано дерево с форматом:
4
/ \
2 7
и передавая значение поиска 2, преемник по порядку будет 4.
Соответствующий код:
template <typename T, typename Compare=std::less<T>>class BinarySearchTree {
private:
struct Node {
// Default constructor - does nothing
Node() {}
// Custom constructor provided for convenience
Node(const T &datum_in, Node *left_in, Node *right_in)
: datum(datum_in), left(left_in), right(right_in) { }
T datum;
Node *left;
Node *right;
};
И вот моя функция поиска преемника в порядке
static Node * min_greater_than_impl(Node *node, const T &val, Compare less) {
// base case: empty tree
if (node == nullptr) {
return nullptr;
}
// base case: no such element exists
if (less((max_element_impl(node))->datum, val) || (!less((max_element_impl(node))->datum, val)
&& !less(val, (max_element_impl(node))->datum))){
return nullptr;
}
// recursive case: go right
if (less(node->datum, val)) {
if (node->right != nullptr) {
return min_greater_than_impl(node->right, val, less);
}
}
// recursive case: go left
else if (less(val, node->datum)) {
if (node->left != nullptr) {
return min_greater_than_impl(node->left, val, less);
}
}
// recurisve case: nequal to node, go right
else {
if (node->right != nullptr) {
return min_greater_than_impl(node->right, val, less);
}
}
return node;
}
Теперь я считаю, что проблема в том, что моя функция не распознает, когда она на самом деле находится в нужном узле. Я думаю, что мне нужно проверить это в дополнительном базовом случае или, возможно, в другом операторе if в конце функции. Тем не менее, я не могу придумать, как это сделать без рекурсивного вызова на текущем узле, но это просто приведет к бесконечному циклу.
Самый простой способ сделать это — добавить родительский указатель. Затем, чтобы получить «следующий», поднимайтесь, пока не найдете родного брата.
Если вы не можете использовать родителя, часто по уважительным причинам (например, дерево допускает дублирование дочерних ветвей), вы должны сохранять свой собственный стек родительских объектов при спуске. Чтобы получить следующий объект, если мы левый лист, это родитель, если мы правый лист, то если родитель — левый лист, это прародитель, в противном случае нам нужно подняться и проверить, является ли прародитель левым. лист прадеда. (Если мы попали в корень, то наш узел стал последним правым листом).
Других решений пока нет …