地 狱 绘 图
查看原帖
地 狱 绘 图
217415
xL1998楼主2021/9/22 18:26
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>

using namespace std;

template <typename _Ty>
struct TreeNode
{
    _Ty val; int nodes, repeatr;
    TreeNode<_Ty> *left, *right, *parent;
    TreeNode(_Ty x, TreeNode<_Ty>* left, TreeNode<_Ty>* right) : val(x), left(left), right(right)
    {
        if (left)  left->parent  = this;
        if (right) right->parent = this;
        
        nodes += (left->nodes + right->nodes + this->repeatr);
    }
    TreeNode(_Ty x, TreeNode<_Ty>* parent = nullptr, int repeats = 1) : val(x), parent(parent), repeatr(repeats)
    { left = right = nullptr; nodes = 1; }

    bool is_leaf() { return !(this->left || this->right); }
};

template <typename _Ty>
class BinaryTree
{
    protected:
    TreeNode<_Ty> *root;
    
    TreeNode<_Ty>* __constructBinaryTree(_Ty arr[], int &n);
    TreeNode<_Ty>* constructBinaryTree(_Ty arr[])
    {
        int n = 0;
        return __constructBinaryTree(arr, n);
    }
    
    void releaseBinaryTree(TreeNode<_Ty>* root);


    public:
    BinaryTree(_Ty arr[]) { root = constructBinaryTree(arr); root->parent = NULL; }
    BinaryTree() { cout << "constructed\n"; root = NULL; }
    ~BinaryTree() { releaseBinaryTree(root); }

    TreeNode<_Ty>* get_root() { return root; }

    void traverse_pre   (TreeNode<_Ty>* root, vector<_Ty>& alloc);
    void traverse_in    (TreeNode<_Ty>* root, vector<_Ty>& alloc);
    void traverse_post  (TreeNode<_Ty>* root, vector<_Ty>& alloc);
    void traverse_layer (TreeNode<_Ty>* root, vector<_Ty>& alloc);
};


// construction & deconstruction
template<typename _Ty>
TreeNode<_Ty>* BinaryTree<_Ty>::__constructBinaryTree(_Ty arr[], int &n)
{
    _Ty ch = arr[n]; n++;
    if (ch == '#') return NULL;

    return new TreeNode<_Ty>(ch, __constructBinaryTree(arr, n), __constructBinaryTree(arr, n));
}

template<class _Tp>
void BinaryTree<_Tp>::releaseBinaryTree(TreeNode<_Tp>* root)
{
    if (root)
    {
        releaseBinaryTree(root->left);
        releaseBinaryTree(root->right);
        delete root;
    }
}


template <typename _Tp>
class BinarySearchTree : virtual public BinaryTree<_Tp>
{
    protected:
        int tot_elements = 0;
        const int __err_nullptr      = 0x7fffffff;
        const int __err_out_of_range = -__err_nullptr;

        int __query_node_rank(TreeNode<_Tp>* node, _Tp value);
        _Tp __find_nth_node  (TreeNode<_Tp>* node, int value);
    public:
        int node_size(TreeNode<_Tp>* node) { return node ? node->nodes : 0; }
        int normalize(TreeNode<_Tp>* p, int err_code) { return p ? p->val : err_code; }

        BinarySearchTree() : BinaryTree<_Tp>() {}
        int size()   { return tot_elements; }
        bool empty() { return size() == 0; }

        // common tools
        void add_node(_Tp value);

        TreeNode<_Tp>* find_node(_Tp value)
        {
            TreeNode<_Tp>* node = this->root;
            while (node && node->val != value) node = value < node->val ? node->left : node->right;
            return node;
        }

        int query_node_rank (_Tp value) { return __query_node_rank (this->root, value) + 1; }
        _Tp find_nth_node   (int n)     { return __find_nth_node   (this->root, n); }

        TreeNode<_Tp>* predecessor_of (TreeNode<_Tp>* node);
        int predecessor_of (_Tp value) { return normalize(predecessor_of (find_node(value)), __err_nullptr); }
        TreeNode<_Tp>* successor_of   (TreeNode<_Tp>* node);
        int successor_of   (_Tp value) { return normalize(successor_of   (find_node(value)), __err_out_of_range); }

        // a few traverse functions
        void traverse_layer (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_layer (this->root, alloc); }
        void traverse_pre   (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_pre   (this->root, alloc); }
        void traverse_in    (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_in    (this->root, alloc); }
        void traverse_post  (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_post  (this->root, alloc); }
};

template <typename _Tp>
//void BinarySearchTree<_Tp>::add_node(TreeNode<_Tp>* root, _Tp value)
void BinarySearchTree<_Tp>::add_node(_Tp value)
{
    if (!this->root)
        this->root = new TreeNode<_Tp>(value);
    else
    {
        int cmp = 0;
        TreeNode<_Tp> *node = this->root, *parent = this->root;
        while (node)
        {
            cmp = node->val - value; parent = node;
            parent->nodes++;

            if      (cmp > 0) node = parent->left;
            else if (cmp < 0) node = parent->right; 
            else            { node->repeatr++; return; }
        }

        TreeNode<_Tp> *newNode = new TreeNode<_Tp>(value, parent);
        cmp > 0 ? parent->left = newNode : parent->right = newNode;
    }

    tot_elements++;
    return;
}

template <typename _Tp>
int BinarySearchTree<_Tp>::__query_node_rank(TreeNode<_Tp>* node, _Tp value)
{
    try
    {
        if (!node) return 0;
    
        int rank = node_size(node->left);
        if (node->val == value) return rank;

        if (node->val < value)
            return __query_node_rank(node->right, value) + rank + node->repeatr;
        else return __query_node_rank(node->left, value);
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
        return __err_out_of_range;
    }
}


template <typename _Tp>
_Tp BinarySearchTree<_Tp>::__find_nth_node(TreeNode<_Tp>* node, int value)
{
    try
    {
        if (!node) return __err_nullptr;
        int rank = node_size(node->left);
        if (rank >= value)
            return __find_nth_node(node->left, value);
        if (rank + node->repeatr >= value) return node->val;
        else return __find_nth_node(node->right, value - rank - node->repeatr);
    }
    catch (const exception& e)
    {
        cout << e.what() << endl;
        return __err_nullptr;
    }
}

template<typename _Tp>
TreeNode<_Tp>* BinarySearchTree<_Tp>::predecessor_of(TreeNode<_Tp>* node)
{
    if (!node) return nullptr;
    
    TreeNode<_Tp> *child = node->left;
    if (child)
    {     
        while (child->right) child = child->right;
        return child;
    }
    else
    {
        TreeNode<_Tp> *parent = node;
        while (parent->parent && parent == parent->parent->left) parent = parent->parent;
        return parent->parent;
    }
}

template <typename _Tp>
TreeNode<_Tp>* BinarySearchTree<_Tp>::successor_of(TreeNode<_Tp>* node)
{
    if (!node) return nullptr;

    TreeNode<_Tp> *child = node->right;
    if (child)
    {
        while (child->left) child = child->left;
        return child;
    }
    else
    {
        TreeNode<_Tp> *parent = node;
        while (parent->parent && parent == parent->parent->right) parent = parent->parent;
        return parent->parent;
    }
}

#define BST BinarySearchTree


int main()
{
    int n; cin >> n; vector<int> v;
    BST<int> *bst = new BST<int>();
    for (int i = 0; i < n; i++)
    {
        int op, x; cin >> op >> x;
        switch (op)
        {
        case 1:
            cout << bst->query_node_rank(x) << endl;
            break;
        case 2:
            cout << bst->find_nth_node(x)   << endl;
            break;
        case 3:
            cout << bst->predecessor_of(x)  << endl;
            break;
        case 4:
            cout << bst->successor_of(x)    << endl;
            break;
        case 5:
            bst->add_node(x);
            break;
        }
    }

    delete bst;
    return 0;
}

本地可以,交上去出现了 蜜 汁 错 误

2021/9/22 18:26
加载中...