1. 程式人生 > >Trie樹基本操作

Trie樹基本操作

#include <iostream>
#include <stack>

using namespace std;

const int sonnum=26, base='a';

struct Trie{
      int num;  //記錄有多少個單詞能到達次,也即相同字首的個位
      bool terminal; //判斷是否是結束節點
      struct Trie *son[sonnum];
      Trie()
      {
          num=1; terminal=false;
          memset(son,NULL,sizeof(son));
      }
};

Trie* NewTrie()
{
    Trie *temp=new Trie();
    return temp;
}

void Insert(Trie *root, char *s)
{
    Trie *temp=root;
    while(*s)
    {
        if(temp->son[*s-base]==NULL)   //不存在 則建立
                   temp->son[*s-base]=NewTrie();
        else 
                temp->son[*s-base]->num++;
        temp=temp->son[*s-base];
        s++;
    }
    temp->terminal=true;  //到達尾部,標記一個串
}

bool Search(Trie *root, char *s)
{
    Trie *temp=root;
    while(*s)
    {
        if(temp->son[*s-base]!=NULL) 
            temp=temp->son[*s-base];
        else
            return false;
        s++;
    }
    return true;
}

void DeleteAll(Trie *root)  //刪除全部節點
{
    Trie *temp=root;
    for(int i=0; i<sonnum; i++)
    {
        if(root->son[i]!=NULL)
            DeleteAll(root->son[i]);
    }
    delete root;
}

bool DeleteWord(Trie *root,char *word)   //刪除某個單詞
{
    Trie *current=root;
    stack<Trie*> nodes;  //用來記錄經過的中間節點,供以後自上而下的刪除
    while(*word && current!=NULL)
    {
         nodes.push(current); //經過的中間節點壓棧
         current=current->son[*word-base];
         word++;
    }
    if(current && current->terminal)  //此時current指向該word對應的最後一個節點
    { 
          while(nodes.size()!=0)
          {
              char c=*(--word);
              current=nodes.top()->son[c-base];  //取得當前處理的節點
              if(current->num==1)  //判斷該節點是否只被word用,若不是,則不能刪除
              {
                  delete current;
                  nodes.top()->son[c-base]=NULL;  //把上層的節點next中指向current節點的指標置為NULL
                  nodes.pop();
              }
              else  //不能刪,只把num相應減1
              {
                  current->num--;
                  nodes.pop();
                  while(nodes.size()!=0)
                  {
                       char *c=--word;
                       current=nodes.top()->son[*c-base];
                       current->num--;
                       nodes.pop();
                  }
                  break;
              }
          }
          return true;
    }
    else
        return false;
}



int main()
{
    Trie *root=NewTrie();
    Insert(root,"a");
    Insert(root,"abandon");
    Insert(root,"abandoned");
    //不存在的情況
    if(Search(root,"abc"))
        printf("Found!\n");
    else
        printf("NotFound!\n");
    //存在的情況
    if(Search(root,"abandon"))
         printf("Found!\n");
    else
        printf("NotFound!\n");
    //能找到 並刪除
    if(DeleteWord(root,"abandon"))
        printf("Delete!\n");
    else
        printf("NotFound\n");
    //找不到
    if(DeleteWord(root,"abc"))
        printf("Delete!\n");
    else
        printf("NotFound!\n");
    
    return 0;
}