字典樹 trie樹 學習


一字典樹

字典樹,又稱單詞查找樹,Trie樹,是一種樹形結構,哈希表的一個變種
 
二.性質
根節點不包含字符,除根節點以外的每一個節點都只包含一個字符;

從根節點到某一節點,路徑上經過的字符串連接起來,為該節點對應的字符串;

每個節點的所有子節點包含的字符都不相同。 

三.優勢: 利用字符串的公共前綴,節約存儲空間和查找時間。時間復雜度O(n)
 
四.適用於:快速字符串插入,查找字符串,在大量字符串的查找中,體現其高效性。
 
查找的時間復雜度只和樹的深度有關,跟表中有多少個單詞無關。
樹的深度與單詞的長度有關:
每個節點代表字符串下的一個字母,那么單詞的每一個字母獨占樹的一層的位置,沒有單詞的兩個字母在同一層級,
則整個樹高為(最長字符串+1), + 1因為root 節點獨占頂層
 
 
五.應用
 
(1)排序:
  排序:使用數組創建模擬字典樹:將字母序列轉化成數字序列 ,標記為數組索引,那么數組索引有序,字母即有序。( 參考上圖,前序遍歷即排序
對樹進行前序遍歷 就是有序排序了。
  
 (2)統計單詞/字符串出現次數
       字典樹的結構體:
       
   count即為統計的串出現的次數 
 
 (3) 查找公共前綴字符串
 
使用舉例:
/*
 字典樹學習:
 
 輸入n個單詞  舉出一個單詞出現的次數。
 
 10
 
 apple
 ppppp
 hello
 hello
 need
 bee
 bee
 none
 you
 apple
 
 
 need
 ==1
 ==Program ended with exit code: 0
 
 */
//
//  main.cpp
//  CPlusDemo
//
//  Created by HF on 2018/5/15.
//  Copyright © 2018年 HF-Liqun. All rights reserved.
//

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using  namespace std;

#define MAX 26    //the total number of alphabet is 26, a...z

struct DicTrie{
    bool isTerminal;//是否是單詞結束標志
    int  count;     //當前字符串出現次數
    struct DicTrie *next[MAX ]; //每個節點 最多 有 MAX 個孩子節點 結構體嵌套
}   ;

DicTrie *root = NULL; // 根節點是一個空節點 特此聲明並賦值

int init()            //初始化鏈表,有對空間要求的 可選用該方法進行初始化
{
    root = new DicTrie;
    root->count = 0;
    for (int  i = 0; i < MAX; i ++) {
        root->next[i] = NULL; // 空節點
        root->isTerminal = false; //
    }
    return 0;
}

bool isFindTrie(char *targetString) //判斷是否能在字典樹中查到目標串
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//當前小寫字母對應數字
        if (head->next[res] == NULL) { //如果是空節點 則為否 結束查找
            return false;
        } else {//不為空 更新頭指針 以便繼續往下查找
            head = head->next[res];
        }
    }
    if (head->count > 0) {
        return true;
    }
    return false;
}

int findTrieCount(char *targetString) //判斷是否能在字典樹中查到目標串
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//當前小寫字母對應數字
        if (head->next[res] == NULL) { //如果是空節點 則為否 結束查找
            return false;
        } else {//不為空 更新頭指針 以便繼續往下查找
            head = head->next[res];
        }
    }
    return head->count;
}

int insertTrie(char *targetString)
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//當前小寫字母對應數字
        if (head->next[res] == NULL) { //如果是空節點
            head->next[res] = new DicTrie;//則插入新節點元素
            head = head->next[res]; //更新頭指針 並初始化
            head->count = 0;        //
            for (int j = 0; j < MAX; j ++) {
                head->next[j] = NULL;
                head->isTerminal = false;
            }
        } else {
            head = head->next[res];
        }
    }
    head->count ++;//每次插入一個,響應計數都增加1
    head->isTerminal = true;
    return head->count;
}

int deleteTrie(char *targetString)
{
    int len = strlen(targetString);
    DicTrie *head = root;
    for (int i = 0; i < len; i ++) {
        int res = (int)(targetString[i] - 'a');//當前小寫字母對應數字
        if (head->next[res] == NULL) { //如果是空節點 表示刪除的字符串不在字典中
            return 0;
        } else { //繼續查找
            head = head->next[res];
        }
    }
    head->count --;//每次刪除一個,響應計數都-1
    if (head->count <= 0) {
        head->count = 0;
        head->isTerminal = false;
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    int n;
    char targetString[20];
    
    init();
    
    scanf("%d",&n); //n 組數據
    for (int i = 0; i < n; i ++) {
        scanf("%s",targetString);
        //字符串插入字典樹
        insertTrie(targetString);//插入方法
    }
    scanf("%s",targetString);
    printf("==%d\n",findTrieCount(targetString));//查找方法
    
    return 0;
}

 

 參考
1.https://blog.csdn.net/piaocoder/article/details/47836559
2.http://blog.51cto.com/570842253/1556652
3.http://pisces.ck.tp.edu.tw/~peng/index.php?action=showfile&file=f743c2923f8170798f62a585257fdd8436cd73b6d
4.https://baike.baidu.com/item/%E5%AD%97%E5%85%B8%E6%A0%91/9825209?fr=aladdin&fromid=517527&fromtitle=Trie%E6%A0%91
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM