使用红黑树实现Map

一、Color类(节点颜色)

/*
   自定义一个枚举类型 Color,它所声明的变量只有REC和BLACK两种值,其必须使用Color.+值的方式进行赋值
 */
public enum Color {
    RED,BLACK
}

二、Pair类(键值对)

/**
 * key-value 对象
 * @param <K> 键
 * @param <V> 值
 */
public class Pair<K extends Comparable<K>,V>{
    public K key;
    public V value;

    public Pair() {
    }
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public String toString() {
        return "Pair{" +
                "key=" + key +
                ", value=" + value +
                '}';
    }
}

三、RBTNode类(红黑树节点)

/**
 * 红黑树节点(实现Map)
 */
public class RBTNode <K extends Comparable<K>,V>{
    Pair<K,V> pair;// 节点值
    RBTNode<K,V> left;// 左节点
    RBTNode<K,V> right;// 右节点
    Color color;// 节点颜色

    public RBTNode() {
    }

    public RBTNode(Pair<K, V> pair) {
        this.pair = pair;
        this.color = Color.RED;
    }

    @Override
    public String toString() {
        return "RBTNode{" +
                "pair=" + pair +
                ", left=" + left +
                ", right=" + right +
                ", color=" + color +
                '}';
    }
}

四、RBT类(红黑树)

/**
 * 红黑树(实现Map)
 * @param <K> 键
 * @param <V> 值
 */
public class RBT <K extends Comparable<K>,V>{
    public int size;// 节点数目

    /**
     * 获取树中的节点数目
     * @return
     */
    public int getSize(){
        return this.size;
    }

    /**
     * 判断当前节点的颜色是否为红色
     * @param node 当前节点
     * @return 是否
     */
    private boolean isRead(RBTNode node){
        if(node == null) return false;
        return node.color == Color.RED;
    }

    /**
     * 左旋当前节点并将新节点返回
     * @param node 当前节点
     * @return 新节点
     */
    private RBTNode leftRotate(RBTNode node){
        RBTNode X = node.right;
        RBTNode T2 = X.left;
        node.right = T2;
        X.left = node;
        // 将旧节点颜色赋给新节点
        X.color = node.color;
        // 将红色赋给旧节点
        node.color = Color.RED;
        return X;
    }

    /**
     * 右旋当前节点并将新节点返回
     * @param node 当前节点
     * @return 新节点
     */
    private RBTNode rightRotate(RBTNode node){
        RBTNode X = node.left;
        RBTNode T2 = X.right;
        node.left = T2;
        X.right = node;
        // 将旧节点颜色赋给新节点
        X.color = node.color;
        // 将旧节点的颜色变为红色
        node.color = Color.RED;
        return X;
    }

    /**
     * 赋值当前节点及左右节点的颜色
     * @param node
     */
    private void reverseColor(RBTNode node){
        node.color = Color.RED;
        node.left.color = Color.BLACK;
        node.right.color = Color.BLACK;
    }

    /**
     * 在当前节点中插入值为pair的节点
     * @param node 当前节点
     * @param pair 节点值
     * @return 新节点
     */
    public RBTNode<K,V> insert(RBTNode<K,V> node,Pair<K,V> pair){
         if(node ==  null){
             size++;
             return new RBTNode<>(pair);
         }
         if(pair.key.compareTo(node.pair.key) == 0){
             node.pair.value = pair.value;
         }else if(pair.key.compareTo(node.pair.key) < 0){
             node.left = insert(node.left, pair);
         }else{
             node.right = insert(node.right, pair);
         }

         // 调整节点位置和节点颜色
        // 三个顺序操作,即对当前节点都要进行的操作
        // 左旋操作
        if(isRead(node.right) && !isRead(node.left)){
            node = leftRotate(node);
        }
        // 右旋操作
        if(isRead(node.left) && isRead(node.left.left)){
            node = rightRotate(node);
        }
        // 颜色翻转
        if(isRead(node.left) && isRead(node.right)){
            reverseColor(node);
        }

        return node;
    }

    /**
     * 在当前节点中获取键为key的节点
     * @param node 当前节点
     * @param key 键值
     * @return 键为key的节点
     */
    public RBTNode<K,V> get(RBTNode<K,V> node,K key){
        if(node == null) return null;
        if(key.compareTo(node.pair.key) == 0){
           return node;
        }else if(key.compareTo(node.pair.key) < 0){
           return get(node.left, key);
        }else{
           return get(node.right, key);
        }
    }

    /**
     * 中序遍历当前节点
     * @param node 当前节点
     */
    public void inOrder(RBTNode node){
        if(node == null) return;
        inOrder(node.left);
        System.out.println(node.pair.key+":"+node.pair.value);
        inOrder(node.right);
    }
}

五、TestRBT(测试)

public class TestRBT {
    public static void main(String[] args) {
        RBT<Integer,Integer> tree = new RBT<>();
        RBTNode<Integer,Integer> root = null;
        root = tree.insert(root, new Pair<>(24, 244));
        root = tree.insert(root, new Pair<>(51, 511));
        root = tree.insert(root, new Pair<>(11, 111));
        root = tree.insert(root, new Pair<>(23, 233));
        root = tree.insert(root, new Pair<>(47, 477));
        root.color = Color.BLACK;
        tree.inOrder(root);
        System.out.println(tree.getSize());
        System.out.println(tree.get(root, 11));
    }
}

当然,我可以帮你实现一个基于红黑树Map数据结构。下面是一个简单的C++代码示例: ```cpp #include <iostream> enum Color { RED, BLACK }; template <typename K, typename V> struct Node { K key; V value; Color color; Node* left; Node* right; Node* parent; // 构造函数 Node(const K& k, const V& v, Color c = RED) : key(k), value(v), color(c), left(nullptr), right(nullptr), parent(nullptr) {} }; template <typename K, typename V> class RBTreeMap { public: RBTreeMap() : root(nullptr) {} // 向红黑树中插入键值对 void insert(const K& key, const V& value) { Node<K, V>* node = new Node<K, V>(key, value); if (root == nullptr) { root = node; node->color = BLACK; } else { Node<K, V>* curr = root; Node<K, V>* parent = nullptr; while (curr != nullptr) { parent = curr; if (key < curr->key) curr = curr->left; else if (key > curr->key) curr = curr->right; else { curr->value = value; // 更新值 return; } } node->parent = parent; if (key < parent->key) parent->left = node; else parent->right = node; insertFixup(node); } } // 查找指定键的值 V find(const K& key) const { Node<K, V>* curr = root; while (curr != nullptr) { if (key < curr->key) curr = curr->left; else if (key > curr->key) curr = curr->right; else return curr->value; } return V(); // 未找到,返回默认值 } private: Node<K, V>* root; // 对红黑树进行修复以维持红黑树的性质 void insertFixup(Node<K, V>* node) { while (node->parent != nullptr && node->parent->color == RED) { if (node->parent == node->parent->parent->left) { Node<K, V>* uncle = node->parent->parent->right; if (uncle != nullptr && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rotateLeft(node); } node->parent->color = BLACK; node->parent->parent->color = RED; rotateRight(node->parent->parent); } } else { Node<K, V>* uncle = node->parent->parent->left; if (uncle != nullptr && uncle->color == RED) { node->parent->color = BLACK; uncle->color = BLACK; node->parent->parent->color = RED; node = node->parent->parent; } else { if (node == node->parent->left) { node = node->parent; rotateRight(node); } node->parent->color = BLACK; node->parent->parent->color = RED; rotateLeft(node->parent->parent); } } } root->color = BLACK; } // 左旋 void rotateLeft(Node<K, V>* node) { Node<K, V>* rightChild = node->right; node->right = rightChild->left; if (rightChild->left != nullptr) rightChild->left->parent = node; rightChild->parent = node->parent; if (node->parent == nullptr) root = rightChild; else if (node == node->parent->left) node->parent->left = rightChild; else node->parent->right = rightChild; rightChild->left = node; node->parent = rightChild; } // 右旋 void rotateRight(Node<K, V>* node) { Node<K, V>* leftChild = node->left; node->left = leftChild->right; if (leftChild->right != nullptr) leftChild->right->parent = node; leftChild->parent = node->parent; if (node->parent == nullptr) root = leftChild; else if (node == node->parent->left) node->parent->left = leftChild; else node->parent->right = leftChild; leftChild->right = node; node->parent = leftChild; } }; int main() { RBTreeMap<int, std::string> map; map.insert(1, "one"); map.insert(2, "two"); map.insert(3, "three"); map.insert(4, "four"); std::cout << map.find(2) << std::endl; // 输出: two std::cout << map.find(5) << std::endl; // 输出: 空字符串(默认值) return 0; } ``` 这个示例使用红黑树实现了一个简单的Map数据结构。你可以使用`insert`方法向Map中插入键值对,使用`find`方法查找指定键的值。注意,这只是一个简单的实现,还可以根据需要进行扩展和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值