C++ AVL树:字典的实际使用

C++ AVL树:字典的实际使用,c++,dictionary,avl-tree,C++,Dictionary,Avl Tree,我想使用AVL树结构作为字典下的基础。 我的班级: template <typename keyType, typename dataType> class AVLTree { class Node { public: keyType key; dataType data; short int balanceFactor; Node * left; Node * right;

我想使用AVL树结构作为字典下的基础。 我的班级:

template <typename keyType, typename dataType>
class AVLTree
{
  class Node
  {
  public:
         keyType key;
         dataType data;
         short int balanceFactor;
         Node * left;
         Node * right;

         Node(const keyType & newKey, const dataType & newData) : key(newKey), data(newData), balanceFactor(0), left(NULL), right(NULL) {};
  };
  Node * Root;
***methods
void insert(AVLTree<keyType, dataType>::Node* & subtreeRoot,  const keyType & newKey, const dataType & newData); //insert new element
  void clear(AVLTree<keyType, dataType>::Node* & subtreeRoot); //clear whole tree
  void graph(AVLTree<keyType, dataType>::Node* const & subtreeRoot, int indent) const; //print tree
  void printDes(AVLTree<keyType, dataType>::Node* const & subtreeRoot) const; //print in descending order
  void printAsc(AVLTree<keyType, dataType>::Node* const & subtreeRoot) const; //print in ascending order
...
public:
  void search(const keyType & findKey) const;
...};
模板
类AVLTree
{
类节点
{
公众:
键型键;
数据类型数据;
短内平衡因子;
节点*左;
节点*右;
节点(constkeytype和newKey,constdatatype和newData):key(newKey),data(newData),balanceFactor(0),left(NULL),right(NULL){};
};
节点*根;
***方法
void insert(AVLTree::Node*&subtreeout,const-keyType&newKey,const-dataType&newData);//插入新元素
void clear(AVLTree::Node*&subtreeRoot);//清除整个树
void图(AVLTree::Node*const&subtreeRoot,int-indent)const;//打印树
void printDes(AVLTree::Node*const&subtreeRoot)const;//按降序打印
void printAsc(AVLTree::Node*const&subtreeRoot)const;//按升序打印
...
公众:
无效搜索(常量键类型和findKey)常量;
...};
假设我有一句话:

我喜欢绿草和绿树。

当我去掉标点符号(“.”)并降低所有单词时:

我喜欢绿草和绿树

我想把AVL树结构中的每一个单词都打印成升序列表:

和-1

草地-1

绿色-2

i-1

类似-1

树-1

其中,第二个“参数”是出现的次数,即绿色时为2

我已经把它作为单链表的映射,但现在我想实现AVL树,我想知道下一步应该做什么。我计划用几个方法制作一个类外计数器,包括这个方法。我的想法是:

  • 重复句子;如果单词(关键字)不存在(搜索方法返回通知-应转换为布尔值?),则将其添加到树中(插入方法)

  • 如果已经存在,则增加第二个参数(在本例中为data)---如何? 如果没有,则将其添加到树中,数据为1

  • 所以,最后一个问题是:我的想法正确吗?如果是这样,那么如何增加模板的第二个参数呢?迭代器是解决这个问题的方法吗


    编辑: 以下是我使用单链表但不使用信息的实现:

    template <typename key>
    class counter {
    sequence<key> list;
    std::map<string, int> map;
    
    public:
    void add_word(key new_word) {
        list.insertEnd(new_word);
    
        auto iterator = map.find(new_word);
        if (iterator != map.end()) {
            iterator->second++;
        } else {
            map.insert({new_word, 1});
        }
    }
    
    模板
    班级计数器{
    序列表;
    地图;
    公众:
    无效添加单词(关键字新单词){
    列表.插入(新单词);
    自动迭代器=map.find(新单词);
    if(迭代器!=map.end()){
    迭代器->第二个++;
    }否则{
    插入({new_word,1});
    }
    }
    

    我想知道的是它可能会起作用:

    template <typename key, typename info>
    class counter {
    AVLTree<key, info> dict;
    std::map<string, int> map;
    
    public:
    void add_word(key new_word) {
        dict.insert(new_word,1);
    
        auto iterator = map.find(new_word);
        if (iterator != map.end()) {
            iterator->second++;
        } else {
            map.insert({new_word, 1});
        }
    }
    ...}
    
    模板
    班级计数器{
    AVLTree dict;
    地图;
    公众:
    无效添加单词(关键字新单词){
    插入(新单词,1);
    自动迭代器=map.find(新单词);
    if(迭代器!=map.end()){
    迭代器->第二个++;
    }否则{
    插入({new_word,1});
    }
    }
    ...}
    

    但是我想它不会像那样工作,所以给定
    数据
    是您想要增加的值,并且它是某种整数类型,您可以简单地执行

    ++found_node->data; 
    
    这就是“增加模板的第二个参数”的意思吗

    请注意,代码示例中的
    search
    方法不会返回任何内容。它可能会向找到的节点返回
    节点*
    或某个迭代器(或
    nullptr
    /end迭代器)


    这对您有帮助吗?

    因此,给定的
    数据是您想要增加的值,并且它是某种整数类型,您只需执行以下操作即可

    ++found_node->data; 
    
    这就是“增加模板的第二个参数”的意思吗

    请注意,代码示例中的
    search
    方法不会返回任何内容。它可能会向找到的节点返回
    节点*
    或某个迭代器(或
    nullptr
    /end迭代器)


    这对您有帮助吗?

    是的,您可以修改
    search
    以返回
    bool
    (但这取决于您希望如何使用它)。如果search返回
    false
    ,您必须调用
    insert

    您似乎没有明确区分要向AVLtree映射用户公开的API

    增量第二个参数(在本例中为数据)——如何

    这取决于您的用例,但让我建议几件事。您将此计数作为
    节点内的卫星
    数据
    进行维护。通常,映射是作为包含节点的树实现的(按住键)指向相应的值。在您的情况下,您只需要跟踪计数。最好将其存储在节点中(正如您已经做的那样)。我更喜欢一个通用的
    insert
    函数,它只接受

    insert
    将遍历树,搜索(
    search
    insert
    中调用表单)。如果元素已经存在,它只会增加与持有键的节点关联的计数器。否则,它将创建一个新的
    节点,并将
    数据设置为
    1

    您的
    AVLTree
    将被实例化为,
    AVLTree-tree
    。当我第一次调用
    tree.insert(“绿色”)
    时,我希望关联的
    数据
    值设置为
    1
    。如果我下次调用
    tree.insert(“绿色”)
    ,它应该设置为
    2

    请注意,您的
    map
    缺少一个关键API,该API为“与该键相关联的值/数据是多少,k?”。
    tree.get(“绿色”)
    应返回计数

    map
    用户不会关心分离输入和准备外部计数。map
    必须处理这个问题。执行
    和-1、grass-1、green-2、i-1,如-1