Trie 字典树 删除操作

字典树的删除操作:

1 没找到直接返回

2 找到叶子节点的时候,叶子节点的count标志清零,代表不是叶子节点了

3 如果当前节点没有其他孩子节点的时候,可以删除这个节点

判断是否需是叶子节点,就检查叶子节点的count标志就可以了。

判断是否有其他孩子节点就需要循环26个节点了,如果都为空,那么就没有其他孩子节点了。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>

class TrieDelete_2
{
    static const int ARRAY_SIZE = 26;
    struct Node
    {
        int val;
        Node *children[ARRAY_SIZE];
        explicit Node(int k = 0) : val(k)
        {
            for (int i = 0; i < ARRAY_SIZE; i++)
            {
                children[i] = NULL;
            }
        }
        ~Node()
        {
            for (int i = 0; i < ARRAY_SIZE; i++)
            {
                if (children[i]) delete children[i];
                children[i] = NULL;
            }
        }
    };

    struct Trie
    {
        Node *emRoot;
        int count;
        explicit Trie(int c = 0) : count(c)
        {
            emRoot = new Node;//emRoot(NULL) {},应该分配emRot空间比较合理
        }
        ~Trie()
        {
            if (emRoot) delete emRoot;
            emRoot = NULL;
        }
    };

    void insert(Trie *trie, char keys[])
    {
        int len = strlen(keys);

        Node *pCrawl = trie->emRoot;
        trie->count++;

        for (int i = 0; i < len; i++)
        {
            int k = keys[i] - 'a';
            if (!pCrawl->children[k])
            {
                pCrawl->children[k] = new Node;
            }
            pCrawl = pCrawl->children[k];
        }
        pCrawl->val = trie->count;
    }

    bool search(Trie *trie, char key[])
    {
        int len = strlen(key);
        Node *pCrawl = trie->emRoot;
        for (int i = 0; i < len; i++)
        {
            int k = key[i] - 'a';
            if (!pCrawl->children[k])
            {
                return false;
            }
            pCrawl = pCrawl->children[k];
        }
        return pCrawl->val != 0;
    }

    bool isFreeNode(Node *n)
    {
        for (int i = 0; i < ARRAY_SIZE; i++)
        {
            if (n->children[i]) return false;
        }
        return true;
    }

    bool isLeaf(Node *n)
    {
        return n->val != 0;
    }

    bool deleteHelp(Node *n, char key[], int lv, int len)
    {
        if (n)
        {
            if (lv == len)
            {
                if (isLeaf(n))
                {
                    n->val = 0;
                    if (isFreeNode(n))
                    {
                        delete n, n = NULL;
                        return true;
                    }
                    return false;
                }
            }
            else
            {
                int k = key[lv] - 'a';
                if(deleteHelp(n->children[k], key, lv+1, len))
                {
                    if (!isLeaf(n) && isFreeNode(n))
                    {
                        delete n, n = NULL;
                        return true;
                    }
                    return false;
                }
            }
        }
        return false;
    }

    void deleteKey(Trie *trie, char key[])
    {
        int len = strlen(key);
        if (len > 0)
        {
            deleteHelp(trie->emRoot, key, 0, len);
        }
    }

public:
    TrieDelete_2()
    {
        char keys[][8] = {"she", "sells", "sea", "shore", "the", "by", "sheer"};
        Trie *trie = new Trie; 

        for(int i = 0; i < ARRAY_SIZE(keys); i++)
        {
            insert(trie, keys[i]);
        }

        deleteKey(trie, keys[0]);

        printf("%s %s\n", "she", search(trie, "she") ? "Present in trie" : "Not present in trie");

        delete trie;
    }
};
    原文作者:Trie树
    原文地址: https://blog.csdn.net/kenden23/article/details/27709217
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞