Algoteka
Log in to submit your own samples!

Treap

Problem by oml1111
# Tech tags Title Creator Created date
1 0
2022-08-01 02:43
View all samples for this language (1 verified and 0 unverified)

Implementation | C++ |

By oml1111 |
0 likes

An implementation of the Treap self-balancing binary search tree data structure. Provides \(O(\log n)\) average time complexity insertion and deletion operations. Allows for \(O(\log n)\) average time search.

Code

#include<deque>
#include<random>
#include<tuple>
 
std::mt19937 randgen;
 
struct Treap {
    struct Node {
        int key;
        int size;
        unsigned int priority;
        
        Node* left_child;
        Node* right_child;
        
        Node(int new_key) {
            key = new_key;
            size = 1;
            priority = randgen();  // Select a random priority
            left_child = NULL;
            right_child = NULL;
        }
        void update() {  // Update the node data after children have been changed
            size = 1;
            if(left_child) size += left_child->size;
            if(right_child) size += right_child->size;
        }
    };
    
    std::deque<Node> nodes;
    Node* root = NULL;
    
    std::pair<Node*, Node*> split(int key, Node* cur) {
        // Split into two subtrees where left subtree contains nodes with smaller keys while right subtree contains all
        // nodes with greater or equal keys
        if(cur == NULL) {
            return {NULL, NULL};
        }
        
        std::pair<Node*, Node*> result;
        if(key <= cur->key) {
            auto ret = split(key, cur->left_child);
            cur->left_child = ret.second;
            result = {ret.first, cur};
        } else {
            auto ret = split(key, cur->right_child);
            cur->right_child = ret.first;
            result = {cur, ret.second};
        }
        cur->update();
        return result;
    }
    
    Node* merge(Node* left, Node* right) {
        // Merges two subtrees together, assuming that all keys of the left subtree are smaller than all the keys in
        // the right subtree
        if(left == NULL) return right;
        if(right == NULL) return left;
        
        Node* top;
        if(left->priority < right->priority) {
            left->right_child = merge(left->right_child, right);
            top = left;
        } else {
            right->left_child = merge(left, right->left_child);
            top = right;
        }
        top->update();
        return top;
    }
    
    void insert(int key) {
        nodes.push_back(Node(key));
        
        std::pair<Node*, Node*> ret = split(key, root);
        root = merge(merge(ret.first, &nodes.back()), ret.second);
    }
    
    void erase(int key) {
        Node *left, *mid, *right;
        
        std::tie(left, mid) = split(key, root);
        std::tie(mid, right) = split(key+1, mid);
        root = merge(left, right);
    }
};
 
 
int main() {
    Treap treap;
    treap.insert(5);
    treap.erase(5);
}

Further reading

Treap (Cartesian tree) - cp-algorithms.com
Treap - wikipedia.org

References

objects
std::mt19937 en.cppreference.com cplusplus.com
classes
std::deque en.cppreference.com cplusplus.com
std::pair en.cppreference.com cplusplus.com
functions
std::deque::push_back en.cppreference.com cplusplus.com
std::mersenne_twister_engine::operator() en.cppreference.com cplusplus.com
std::pair::pair en.cppreference.com cplusplus.com
std::tie en.cppreference.com cplusplus.com

Problem Description

Implement a Treap data structure that tracks the size of the subtree of each node. Insert and element into it and erase an element from it.

View sample discussion (0 comments)
View problem discussion (0 comments)