//
// Created by 423A35C7 on 2023-12-15.
//
// 09:19
// 20:06

#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <vector>

template<typename T>
class BiSortNode {
public:
    using NodePtr = std::unique_ptr<BiSortNode>;
    // 好像这里没法使用initializer_list，initializer_list是对于多个相同值的初始化，而不是一个东西的初始化参数列表
    template<typename... Args>
    explicit BiSortNode(Args... args, std::function<bool(T, T)> _compare) : data(args...) {
        this->compare_function_(_compare);
    }

    template<typename... Args>
    explicit BiSortNode(Args... args) : data(args...) {
        this->compare_function_ = [](T&a, T&b) { return a < b; };
    }

    void update_depth_and_balance_factor() {
        const int left_depth = this->left_child ? this->left_child->depth + 1 : 0;
        const int right_depth = this->right_child ? this->right_child->depth + 1 : 0;
        this->balance_factor = left_depth - right_depth;
        this->depth = std::max(left_depth, right_depth);
    }

    // 这里的左旋指的是LL型需要进行的旋转，名称不一定对
    // 这部分用注释不好解释，建议最好搜一下网上的图解，理解了之后再看这部分代码
    static void left_rotate(NodePtr&unbalanced) {
        NodePtr pivot = std::move(unbalanced->left_child);
        unbalanced->left_child = std::move(pivot->right_child);
        pivot->right_child = std::move(unbalanced);
        unbalanced = std::move(pivot);
        unbalanced->update_depth_and_balance_factor();
        unbalanced->right_child->update_depth_and_balance_factor();
    }

    // 这里的右旋指的是RR型需要进行的旋转，名称不一定对
    // 这部分用注释不好解释，建议最好搜一下网上的图解，理解了之后再看这部分代码
    static void right_rotate(NodePtr&unbalanced) {
        NodePtr pivot = std::move(unbalanced->right_child);
        unbalanced->right_child = std::move(pivot->left_child);
        pivot->left_child = std::move(unbalanced);
        unbalanced = std::move(pivot);
        unbalanced->update_depth_and_balance_factor();
        unbalanced->left_child->update_depth_and_balance_factor();
    }

    static void insert(NodePtr&current_node, T new_data) {
        // int balance_diff = 0;
        if (new_data < current_node->data) {
            // 如果新的节点比当前节点小就找它的左子树
            if (current_node->left_child == nullptr) {
                current_node->left_child = std::make_unique<BiSortNode>(new_data);
            }
            else {
                current_node->insert(current_node->left_child, new_data);
            }
        }
        else {
            // 否则找右子树
            if (current_node->right_child == nullptr) {
                current_node->right_child = std::make_unique<BiSortNode>(new_data);
            }
            else {
                current_node->insert(current_node->right_child, new_data);
            }
        }
        current_node->update_depth_and_balance_factor();
        if (current_node->balance_factor > 1) {
            // 左子树比右子树高
            assert(current_node->left_child->balance_factor != 0); // 此时左子树的平衡因子不应为0
            if (current_node->left_child->balance_factor < 0) // 符合LR型
                current_node->right_rotate(current_node->left_child); // 先进行右旋（逆时针），转化为LL
            current_node->left_rotate(current_node); // 左旋（顺时针）
        }
        else if (current_node->balance_factor < -1) {
            // 右子树比左子树高
            assert(current_node->right_child->balance_factor != 0); // 此时右子树的平衡因子不应为0
            if (current_node->right_child->balance_factor > 0) // 符合RL型
                current_node->left_rotate(current_node->right_child); // 先进行左旋（顺时针），转化为RR型
            current_node->right_rotate(current_node); // 右旋（逆时针）
        }
        // current_node->balance_factor += balance_diff;
        current_node->update_depth_and_balance_factor();
        // return balance_diff;
    }

    void inorder_traversal(std::vector<T>&output) {
        if (this->left_child != nullptr) this->left_child->inorder_traversal(output);
        output.push_back(this->data);
        if (this->right_child != nullptr) this->right_child->inorder_traversal(output);
    }

    void preorder_traversal(std::vector<T>&output) {
        output.push_back(this->data);
        if (this->left_child != nullptr) this->left_child->preorder_traversal(output);
        if (this->right_child != nullptr) this->right_child->preorder_traversal(output);
    }

    void postorder_traversal(std::vector<T>&output) {
        if (this->left_child != nullptr) this->left_child->postorder_traversal(output);
        if (this->right_child != nullptr) this->right_child->postorder_traversal(output);
        output.push_back(this->data);
    }

    void traverse_and_output(std::ostream&out, std::function<void(std::vector<T>&)> traverse_function) {
        std::vector<T> traverse_result;
        traverse_function(traverse_result);
        for (auto const&i: traverse_result)
            std::cout << i << " ";
        std::cout << std::endl;
    }

private:
    NodePtr left_child;
    NodePtr right_child;
    int balance_factor = 0; // 平衡因子
    int depth = 0; // 树的深度（高度）
    T data;
    std::function<bool(T&, T&)> compare_function_;
};


int main() {
    std::vector<int> origin_vector;
    int temp;
    while (std::cin >> temp) {
        origin_vector.push_back(temp);
    }
    auto generator = origin_vector.cbegin();
    BiSortNode<int>::NodePtr bi_sort_node{new BiSortNode<int>(*generator++)};
    while (generator != origin_vector.cend()) {
        bi_sort_node->insert(bi_sort_node, *generator++);
    }
    std::vector<int> traversal_result;
    bi_sort_node->inorder_traversal(traversal_result);
    std::cout << "为了便于验证，以下依次输出平衡二叉树的前序、中序、后序遍历结果：" << std::endl;
    bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
        bi_sort_node->preorder_traversal(output);
    });
    bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
        bi_sort_node->inorder_traversal(output);
    });
    bi_sort_node->traverse_and_output(std::cout, [&bi_sort_node](std::vector<int>&output) {
        bi_sort_node->postorder_traversal(output);
    });
    return 0;
}

// 输入：
// 98 77 94 67 59 60 56 68 95 98 32 39 32 17 5 5 8 19 40 41

// 输出：
// 为了便于验证，以下依次输出平衡二叉树的前序、中序、后序遍历结果：
// 67 39 17 5 5 8 32 19 32 59 41 40 56 60 94 77 68 98 95 98
// 5 5 8 17 19 32 32 39 40 41 56 59 60 67 68 77 94 95 98 98
// 5 8 5 19 32 32 17 40 56 41 60 59 39 68 77 95 98 98 94 67
