21xrx.com
2024-05-20 15:46:02 Monday
登录
文章检索 我的文章 写文章
C++ Map的实现
2023-07-13 10:02:19 深夜i     --     --
C++ Map 实现

C++中的Map是一种非常常用的数据结构,它的实现是基于关联数组的概念,用于存储 键-值 对的集合,其中每个键都是唯一的。Map容器通过一个红黑树实现,它具有自平衡的特性,可以在插入,删除和查找操作中进行自动调整,使得这些操作都具有O(log n)的时间复杂度。

在实现Map时,我们需要考虑两个方面:容器内部的实现和容器外部的访问接口。在实现内部,我们需要定义Map的节点结构体和迭代器结构体,同时还要定义Map的成员函数,例如插入,删除,查找等操作。下面是一个简单的Map内部实现的伪代码:


template <typename Key, typename Value>

struct MapNode{

  Key key;

  Value value;

  MapNode *left;

  MapNode *right;

};

template <typename Key, typename Value>

class Map{

public:

  Map() : root(nullptr), size(0){};

  void insert(const Key& key, const Value& value);

  bool remove(const Key& key);

  Value& operator[](const Key& key);

private:

  MapNode<Key, Value> *root;

  int size;

  ...

};

Map的节点结构体包含了键,值和左右子节点指针。容器内部主要实现了插入,删除和查找三个操作。待实现代码如下:


template<typename Key, typename Value>

void Map<Key, Value>::insert(const Key& key, const Value& value){

  MapNode<Key, Value>* node = new MapNode<Key, Value> nullptr;

  if (!root)

    root = node;

  

  else{

    MapNode<Key, Value>* curr = root;

    while (curr) {

      if (key < curr->key) {

        if (!curr->left)

          curr->left = node;

          break;

        

        else

          curr = curr->left;

        

      }

      else if (key > curr->key) {

        if (!curr->right)

          curr->right = node;

          break;

        

        else

          curr = curr->right;

        

      }

      else

        curr->value = value;

        return;

      

    }

  }

  size++;

}

template<typename Key, typename Value>

bool Map<Key, Value>::remove(const Key& key){

  MapNode<Key, Value>* to_del = root;

  MapNode<Key, Value>* parent_to_del = nullptr;

  while (to_del && to_del->key != key) {

    parent_to_del = to_del;

    if (to_del->key > key)

      to_del = to_del->left;

    else

      to_del = to_del->right;

  }

  if (!to_del) return false;

  if (!to_del->right) {

    if (!parent_to_del)

      root = to_del->left;

    

    else {

      if (to_del == parent_to_del->left)

        parent_to_del->left = to_del->left;

      else

        parent_to_del->right = to_del->left;

    }

  }

  else {

    MapNode<Key, Value>* left_most = to_del->right;

    while (left_most->left)

      left_most = left_most->left;

    

    left_most->left = to_del->left;

    if (!parent_to_del)

      root = to_del->right;

    

    else{

      if (to_del == parent_to_del->left)

        parent_to_del->left = to_del->right;

      

      else

        parent_to_del->right = to_del->right;

      

    }

  }

  delete to_del;

  size--;

  return true;

}

template<typename Key, typename Value>

Value& Map<Key, Value>::operator[](const Key& key){

  MapNode<Key, Value>* curr = root;

  while (curr) {

    if (key == curr->key)

      return curr->value;

    

    else if (key < curr->key){

      if (!curr->left) {

        MapNode<Key, Value>* node = new MapNode<Key, Value>{ key, Value(), nullptr, nullptr };

        curr->left = node;

        size++;

        return node->value;

      }

      else

        curr = curr->left;

      

    }

    else{

      if (!curr->right) {

        MapNode<Key, Value>* node = new MapNode<Key, Value>{ key, Value(), nullptr, nullptr };

        curr->right = node;

        size++;

        return node->value;

      }

      else

        curr = curr->right;

      

    }

  }

  return root->value;

}

在Map的外部,我们需要定义一些访问接口,例如迭代器和操作符重载,这些都是用户可以使用的公共接口。下面是一个简单的访问接口的伪代码:


template<typename Key, typename Value>

class Map{

public:

  Map() : root(nullptr), size(0){};

  void insert(const Key& key, const Value& value);

  bool remove(const Key& key);

  Value& operator[](const Key& key);

  class iterator{

    MapNode<Key, Value>* curr;

    iterator(MapNode<Key, Value>* node) : curr(node){};

    ...

  };

  iterator begin() const;

  iterator end() const;

  ...

};

template<typename Key, typename Value>

typename Map<Key, Value>::iterator Map<Key, Value>::begin() const{

  return iterator(get_left_most_node(root));

}

template<typename Key, typename Value>

typename Map<Key, Value>::iterator Map<Key, Value>::end() const{

  return iterator(nullptr);

}

template<typename Key, typename Value>

typename Map<Key, Value>::iterator::iterator(const iterator& other)

  curr = other.curr;

template<typename Key, typename Value>

typename Map<Key, Value>::iterator& Map<Key, Value>::iterator::operator=(const iterator& other){

  curr = other.curr;

  return *this;

}

template<typename Key, typename Value>

Value& Map<Key, Value>::iterator::operator*()

  return curr->value;

template<typename Key, typename Value>

typename Map<Key, Value>::iterator Map<Key, Value>::iterator::operator++(int){

  MapNode<Key, Value>* prev = curr;

  if (curr->right) {

    curr = get_left_most_node(curr->right);

  } else {

    while (curr->key > prev->key)

      curr = curr->left;

    

  }

  return iterator(prev);

}

通过以上的代码实现,我们可以完成Map的基本功能,同时在程序中使用Map容器时也可以通过容器的访问接口轻松地进行增删改查等操作。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复