STL - map 仿

map set

STL map底层是 红黑树

实现一个支持 for auto 语法的二叉排序树类
有begin() end() 有++ 重载

set 实现
1、用模板改造原有实现
2、进行高级封装,支持set操作 (无需添加其他操作了)

封装map过程中的问题
set 存 int 索引 int
map 存<int, int> 索引 int

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <vector>
using namespace std;

#define BEGINS(x) namespace x {
#define ENDS(x) }

BEGINS(test1)

int main() {
    set<int> s;
    for (int i = 0; i < 5; i++) {
        int val = rand() % 100;
        cout << "insert : " << val << endl;
        s.insert(val);
    }
    for (auto x : s) {
        cout << "output : " << x << endl;
    }
    return 0;
}

ENDS(test1)

BEGINS(test2)

class base_node {
public :
    base_node(
        int key = 0,
        base_node *father = nullptr,
        base_node *lchild = nullptr,
        base_node *rchild = nullptr
    ) : key(key), father(father), lchild(lchild), rchild(rchild) {}
    virtual ~base_node() {}
    void print() {
        cout << key << " | ";
        if (lchild) cout << lchild->key; 
        else cout << "0";
        cout << " , ";
        if (rchild) cout << rchild->key; 
        else cout << "0";
        cout << endl;
        return ;
    }
    int key;
    base_node *father, *lchild, *rchild;

};

class binary_search_node : public base_node {
public :
    typedef base_node node_t;
    binary_search_node(
        int key = 0, 
        node_t *father = nullptr, 
        node_t *lchild = nullptr, 
        node_t *rchild = nullptr
    ) : base_node(key, father, lchild, rchild) {}
    static node_t *insert(node_t *father, node_t *root, int key) {
        if (root == nullptr) return binary_search_node::getNewNode(father, key);
        if (key == root->key) return root;
        if (key < root->key) {
            root->lchild = insert(root, root->lchild, key);
        } else {
            root->rchild = insert(root, root->rchild, key);
        }
        return root;
    }
    static node_t *getNewNode(node_t *father, int key) {
        return new binary_search_node(key, father);
    }
    static node_t *next(node_t *ptr) { //找后继节点
        if (ptr->rchild) { //有右子节点
            ptr = ptr->rchild;
            while (ptr->lchild) ptr = ptr->lchild;
            return ptr;
        }
        while (ptr->father && ptr != ptr->father->lchild) { //找父节点
            ptr = ptr->father;
        }
        return ptr->father;
    }
};

class binary_search_node_iterator {  //迭代器 —— 对原生的指针进行封装的行为
public :
    friend void output_tree(binary_search_node_iterator &);
    typedef base_node node_t;
    typedef binary_search_node_iterator iterator;
    binary_search_node_iterator(node_t *ptr) : ptr(ptr) {}
    bool operator!=(const iterator &iter) {  //  !=
        return ptr != iter.ptr;
    }
    iterator &operator++() { // ++i
        ptr = binary_search_node::next(ptr);
        return *this;
    }
    iterator operator++(int) { // i++
        iterator ret(ptr);
        ptr = binary_search_node::next(ptr);
        return ret;
    }
    int &operator*() {  //重载取值运算
        return ptr->key;
    }

private:
    node_t *ptr;
};

class bs_tree {
public :
    typedef base_node node_t;
    typedef binary_search_node_iterator iterator;
    void insert(int key) {
        root.lchild = binary_search_node::insert(&root, root.lchild, key);
        return ;
    }
    node_t *get_root() { return root.lchild; }
    iterator begin() {
        node_t *p = &root;
        while (p->lchild) p = p->lchild;
        return iterator(p);
    }
    iterator end() { return iterator(&root); }

private:
    binary_search_node root;
};

void output_tree(base_node *p) {
    if (p == nullptr) return ;
    p->print();
    cout << "p next ======" << endl;
    binary_search_node::next(p)->print();
    cout << "p next print done ======" << endl << endl;
    output_tree(p->lchild);
    output_tree(p->rchild);
    return ;
}

int main() {
    bs_tree t; //根节点
    for (int i = 0; i < 5; i++) {
        int val = rand() % 100;
        cout << "insert : " << val << endl;
        t.insert(val);
    }
    for (auto x : t) {
        cout << x << endl;
    }
    return 0;
}

ENDS(test2)

BEGINS(test3)

template<typename T>
class base_node {
public :
    base_node(
        T key = 0,
        base_node *father = nullptr,
        base_node *lchild = nullptr,
        base_node *rchild = nullptr
    ) : key(key), father(father), lchild(lchild), rchild(rchild) {}
    virtual ~base_node() {}
    void print() {
        cout << key << " | ";
        if (lchild) cout << lchild->key; 
        else cout << "0";
        cout << " , ";
        if (rchild) cout << rchild->key; 
        else cout << "0";
        cout << endl;
        return ;
    }
    T key;
    base_node *father, *lchild, *rchild;
};

template<typename T>
class binary_search_node : public base_node<T> {
public :
    typedef base_node<T> node_t;
    binary_search_node(
        T key = 0, 
        node_t *father = nullptr, 
        node_t *lchild = nullptr, 
        node_t *rchild = nullptr
    ) : base_node<T>(key, father, lchild, rchild) {}
    static node_t *insert(node_t *father, node_t *root, T key) {
        if (root == nullptr) return binary_search_node<T>::getNewNode(father, key);
        if (key == root->key) return root;
        if (key < root->key) {
            root->lchild = insert(root, root->lchild, key);
        } else {
            root->rchild = insert(root, root->rchild, key);
        }
        return root;
    }
    static node_t *getNewNode(node_t *father, T key) {
        return new binary_search_node<T>(key, father);
    }
    static node_t *next(node_t *ptr) {
        if (ptr->rchild) {
            ptr = ptr->rchild;
            while (ptr->lchild) ptr = ptr->lchild;
            return ptr;
        }
        while (ptr->father && ptr != ptr->father->lchild) {
            ptr = ptr->father;
        }
        return ptr->father;
    }
};

template<typename T>
class binary_search_node_iterator {
public :
    friend void output_tree(binary_search_node_iterator<T> &);
    typedef base_node<T> node_t;
    typedef binary_search_node_iterator<T> iterator;
    binary_search_node_iterator(node_t *ptr) : ptr(ptr) {}
    bool operator!=(const iterator &iter) {
        return ptr != iter.ptr;
    }
    iterator &operator++() { // ++i
        ptr = binary_search_node<T>::next(ptr);
        return *this;
    }
    iterator operator++(int) { // i++
        iterator ret(ptr);
        ptr = binary_search_node<T>::next(ptr);
        return ret;
    }
    T &operator*() {
        return ptr->key;
    }

private:
    node_t *ptr;
};

template<typename T>
class bs_tree {
public :
    typedef base_node<T> node_t;
    typedef binary_search_node_iterator<T> iterator;
    void insert(const T &key) {
        root.lchild = binary_search_node<T>::insert(&root, root.lchild, key);
        return ;
    }
    node_t *get_root() { return root.lchild; }
    iterator begin() {
        node_t *p = &root;
        while (p->lchild) p = p->lchild;
        return iterator(p);
    }
    iterator end() { return iterator(&root); }

private:
    binary_search_node<T> root;
};

template<typename T>
class set { //set 的封装
public :
    typedef typename bs_tree<T>::iterator iterator;
    void insert(const T &key) {
        tree.insert(key);
        return ;
    }
    iterator begin() { return tree.begin(); }
    iterator end() { return tree.end(); }

private:
    bs_tree<T> tree;
};

void output_tree(base_node<int> *p) {
    if (p == nullptr) return ;
    p->print();
    cout << "p next ======" << endl;
    binary_search_node<int>::next(p)->print();
    cout << "p next print done ======" << endl << endl;
    output_tree(p->lchild);
    output_tree(p->rchild);
    return ;
}

int main() {
    test3::set<int> t;
    for (int i = 0; i < 5; i++) {
        int val = rand() % 100;
        cout << "insert : " << val << endl;
        t.insert(val);
    }
    for (auto x : t) {
        cout << x << endl;
    }
    return 0;
}

ENDS(test3)

BEGINS(test4)

template<typename T>
class Select1st {
public :
    auto operator()(T a) -> decltype(a.first) { //返回值后置
        return a.first;
    }
};

template<typename T>
class SelectRaw {
public :
    T operator()(T a) {
        return a;
    }
};

template<typename T>
class less {
public :
    bool operator()(const T &a, const T &b) const {
        return a < b;
    }
};

template<typename T>
class base_node {
public :
    base_node(
        T data = T(),
        base_node *father = nullptr,
        base_node *lchild = nullptr,
        base_node *rchild = nullptr
    ) : data(data), father(father), lchild(lchild), rchild(rchild) {}
    virtual ~base_node() {}
    void print() {
        cout << data << " | ";
        if (lchild) cout << lchild->key; 
        else cout << "0";
        cout << " , ";
        if (rchild) cout << rchild->key; 
        else cout << "0";
        cout << endl;
        return ;
    }
    T data;
    base_node *father, *lchild, *rchild;
};

template<typename K, typename T, typename SKEY, typename CompareK>
class binary_search_node : public base_node<T> {
public :
    typedef base_node<T> node_t;
    binary_search_node(
        T key = T(), 
        node_t *father = nullptr, 
        node_t *lchild = nullptr, 
        node_t *rchild = nullptr
    ) : base_node<T>(key, father, lchild, rchild) {}
    static node_t *insert(node_t *father, node_t *root, T data) {
        if (root == nullptr) return binary_search_node<K, T, SKEY, CompareK>::getNewNode(father, data);
        if (comp(SKEY()(data), SKEY()(root->data))) {
            root->lchild = insert(root, root->lchild, data);
        } else if (comp(SKEY()(root->data), SKEY()(data))) {
            root->rchild = insert(root, root->rchild, data);
        }
        return root;
    }
    static node_t *getNewNode(node_t *father, T key) {
        return new binary_search_node<K, T, SKEY, CompareK>(key, father);
    }
    static node_t *next(node_t *ptr) {
        if (ptr->rchild) {
            ptr = ptr->rchild;
            while (ptr->lchild) ptr = ptr->lchild;
            return ptr;
        }
        while (ptr->father && ptr != ptr->father->lchild) {
            ptr = ptr->father;
        }
        return ptr->father;
    }
    static node_t *find(node_t *root, const K &key) {
        node_t *p = root;
        while (p) {
            if (key < SKEY()(p->data)) {
                p = p->lchild;
            } else if (SKEY()(p->data) < key) {
                p = p->rchild;
            } else {
                break;
            }
        }
        return p;
    }
    static CompareK comp;
};
template<typename K, typename T, typename SKEY, typename CompareK>
CompareK binary_search_node<K, T, SKEY, CompareK>::comp;

template<typename K, typename T, typename SKEY, typename CompareK>
class binary_search_node_iterator {
public :
    friend void output_tree(binary_search_node_iterator<K, T, SKEY, CompareK> &);
    typedef base_node<T> node_t;
    typedef binary_search_node_iterator<K, T, SKEY, CompareK> iterator;
    binary_search_node_iterator(node_t *ptr) : ptr(ptr) {}
    bool operator!=(const iterator &iter) {
        return ptr != iter.ptr;
    }
    iterator &operator++() { // ++i
        ptr = binary_search_node<K, T, SKEY, CompareK>::next(ptr);
        return *this;
    }
    iterator operator++(int) { // i++
        iterator ret(ptr);
        ptr = binary_search_node<K, T, SKEY, CompareK>::next(ptr);
        return ret;
    }
    T &operator*() {
        return ptr->data;
    }

private:
    node_t *ptr;
};

template<typename K, typename T, typename SKEY, typename CompareK>
class bs_tree {
public :
    typedef base_node<T> node_t;
    typedef binary_search_node_iterator<K, T, SKEY, CompareK> iterator;
    void insert(T data) {
        root.lchild = binary_search_node<K, T, SKEY, CompareK>::insert(&root, root.lchild, data);
        return ;
    }
    node_t *find(const K &key) {
        return binary_search_node<K, T, SKEY, CompareK>::find(root.lchild, key);
    }
    node_t *get_root() { return root.lchild; }
    iterator begin() {
        node_t *p = &root;
        while (p->lchild) p = p->lchild;
        return iterator(p);
    }
    iterator end() { return iterator(&root); }

private:
    binary_search_node<K, T, SKEY, CompareK> root;
};

template<typename K, typename V, typename CompareK = test4::less<K>>
class map {
public :
    typedef pair<const K, V> value_type;
    typedef bs_tree<K, value_type, Select1st<value_type>, CompareK> BASE_TREE;
    typedef typename BASE_TREE::iterator iterator;
    typedef typename BASE_TREE::node_t node_t;
    V &operator[](const K &key) {
        node_t *val = tree.find(key);
        if (val) {
            return val->data.second;
        }
        tree.insert(value_type(key, V())); //插入默认键值对
        return tree.find(key)->data.second;
    }
    iterator find(const K &key) {
        node_t *p = tree.find(key);
        if (p == nullptr) return end();
        return iterator(p);
    }
    iterator begin() { return tree.begin(); }
    iterator end() { return tree.end(); }

private:
    BASE_TREE tree;
};

template<typename K, typename CompareK = test4::less<K>>
class set {
public :
    typedef K value_type;
    typedef bs_tree<K, value_type, SelectRaw<value_type>, CompareK> BASE_TREE;
    typedef typename BASE_TREE::iterator iterator;
    typedef typename BASE_TREE::node_t node_t;
    void insert(const value_type &key) {
        tree.insert(key);
        return ;
    }
    iterator find(const K &key) {
        node_t *p = tree.find(key);
        if (p == nullptr) return end();
        return iterator(p);
    }
    
    iterator begin() { return tree.begin(); }
    iterator end() { return tree.end(); }

private:
    BASE_TREE tree;
};

int main() {
    test4::map<int, int> m;
    test4::set<int> s;
    for (int i = 0; i < 5; i++) {
        int key = rand() % 100;
        int val = rand() % 100;
        cout << "key : " << key << ", value : " << val << endl;
        m[key] = val;
        s.insert(val);
    }
    for (auto x : m) {
        cout << x.first << " " << x.second << endl;
    }
    for (auto x : s) {
        cout << x << endl;
    }
    return 0;
}

ENDS(test4)

BEGINS(test5)

class A {
public :
    A() : x(rand() % 100), y(rand() % 100) {}
    int x, y;
};

class CMP {
public :
    bool operator()(const A &a, const A &b) const {
        if (a.x - b.x) return a.x < b.x;
        return a.y < b.y;
    }
};

ostream &operator<<(ostream &out, const A &a) {
    cout << "(" << a.x << ", " << a.y << ")";
    return out;
}

int main() {
    test4::set<A, CMP> s;
    for (int i = 0; i < 5; i++) s.insert(A());
    for (auto x : s) {
        cout << x << endl;
    }
    return 0;
}

ENDS(test5)

int main() {
    // test1::main();
    // test2::main();
    // test3::main();
    // test4::main();
    test5::main();
    return 0; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值