1

Тема: Перевірити чи бінарне дерево збалансоване ітеративним способом

Мені цікаво як перевірити чи бінарне дерево збалансоване ітеративним способом.
Рекурсією виходить ось так:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    int dfs_height(TreeNode* root)
    {
        if (root == nullptr)
            return 0;

        int left_height = dfs_height(root->left);
        

        if (left_height == -1)
            return -1;

        int right_height = dfs_height(root->right);
        

        if (right_height == -1)
            return -1;

        if (abs(left_height - right_height) > 1)
            return -1;

        return max(left_height, right_height) + 1;
    }

public:
    bool isBalanced(TreeNode* root)
    {
        return dfs_height(root) != -1;
    }
};

Пробував просто замінити циклами рекурсію — не виходить.

2

Re: Перевірити чи бінарне дерево збалансоване ітеративним способом

Тут потрібен стек, причому стек трохи хитрий, бо рекурсивних викликів два. Кожен елемент стека має представляти або вказівник на піддерево, або обчислений результат для піддерева, який у подальшому зіллється з результатом праворуч від нього.

Подякували: Teg Miles1

3

Re: Перевірити чи бінарне дерево збалансоване ітеративним способом

Тобто, як я розумію, для пошуку в глибину (depth first search) краще обирати рекурсію, за потреби з мемоізацією.
А для пошуку в ширину (breadth first search) перевага віддається ітеративному методу, наприклад, з чергою.
Бо якщо навпаки робити, вийде доволі апокаліптичне кодло, як от для пошуку в глибину зі стеком.

4

Re: Перевірити чи бінарне дерево збалансоване ітеративним способом

Цикл і рекурсія - лише різні способи запису алгоритмів; ну й в рекурсії є неявний стек для локальних змінних і місця в коді для продовження, але цей стек має фіксований розмір. Пошук у глибину зі стеком я б не назвав апокаліптичним:

Tree *search_depth(Tree *tree, Value value) { // повертаємо знайдений елемент або nullptr
    std::vector<Tree *> stack {tree};
    while(!stack.empty()) {
        Tree *current = stack.pop();
        if(current->value == value)
            return current;
        if(current->right)
            stack->push_back(current->right);
        if(current->left)
            stack->push_back(current->left);
    }
    return nullptr;
}
Подякували: leofun011

5

Re: Перевірити чи бінарне дерево збалансоване ітеративним способом

Тоді чи варто уникати рекурсії? Якщо ні, то в яких випадках вона буде бажана, а в яких ні?