久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

trie樹

 A_Geek 2013-10-03
Trie樹|字典樹(字符串排序)

有時,,我們會碰到對字符串的排序,,若采用一些經(jīng)典的排序算法,,則時間復(fù)雜度一般為O(n*lgn),,但若采用Trie樹,,則時間復(fù)雜度僅為O(n),。

Trie樹又名字典樹,,從字面意思即可理解,,這種樹的結(jié)構(gòu)像英文字典一樣,,相鄰的單詞一般前綴相同,之所以時間復(fù)雜度低,,是因為其采用了以空間換取時間的策略,。

下圖為一個針對字符串排序的Trie樹(我們假設(shè)在這里字符串都是小寫字母),每個結(jié)點有26個分支,,每個分支代表一個字母,,結(jié)點存放的是從root節(jié)點到達(dá)此結(jié)點的路經(jīng)上的字符組成的字符串。

將每個字符串插入到trie樹中,,到達(dá)特定的結(jié)尾節(jié)點時,,在這個節(jié)點上進(jìn)行標(biāo)記,如插入"afb",,第一個字母為a,,沿著a往下,,然后第二個字母為f,沿著f往下,,第三個為b,,沿著b往下,由于字符串最后一個字符為'\0',,因而結(jié)束,,不再往下了,然后在這個節(jié)點上標(biāo)記afb.count++,,即其個數(shù)增加1.

之后,,通過前序遍歷此樹,即可得到字符串從小到大的順序,。

實現(xiàn)代碼如下(g++,、VC++都編譯通過):

復(fù)制代碼
  1 #include <iostream>
  2 #include <string.h>
  3 using namespace std;
  4 
  5 #define NUM 26
  6 
  7 class Node
  8 {
  9 public:
 10     int count; //記錄該處字符串個數(shù)
 11     Node* char_arr[NUM];  //分支
 12     char* current_str;   //記錄到達(dá)此處的路徑上的所有字母組成的字符串
 13     Node();
 14 };
 15 
 16 class Trie
 17 {
 18 public:
 19     Node* root;
 20     Trie();
 21 
 22     void insert(char* str);
 23     void output(Node* &node, char** str, int& count);
 24 };
 25 
 26 //程序未考慮delete動態(tài)內(nèi)存
 27 int main()
 28 {
 29     char** str = new char*[12];
 30     str[0] = "zbdfasd";
 31     str[1] = "zbcfd";
 32     str[2] = "zbcdfdasfasf";
 33     str[3] = "abcdaf";
 34     str[4] = "defdasfa";
 35     str[5] = "fedfasfd";
 36     str[6] = "dfdfsa";
 37     str[7] = "dadfd";
 38     str[8] = "dfdfasf";
 39     str[9] = "abcfdfa";
 40     str[10] = "fbcdfd";
 41     str[11] = "abcdaf";
 42 
 43     //建立trie樹
 44     Trie* trie = new Trie();
 45     for(int i = 0; i < 12; i++)
 46         trie->insert(str[i]);
 47 
 48     int count = 0;
 49     trie->output(trie->root, str, count);
 50 
 51     for(int i = 0; i < 12; i++)
 52         cout<<str[i]<<endl;
 53 
 54     return 0;
 55 }
 56 
 57 Node::Node()
 58 {
 59     count = 0;
 60     for(int i = 0; i < NUM; i++)
 61         char_arr[i] = NULL;
 62     current_str = new char[100];
 63     current_str[0] = '\0';
 64 }
 65 
 66 Trie::Trie()
 67 {
 68     root = new Node();
 69 }
 70 
 71 void Trie::insert(char* str)
 72 {
 73     int i = 0;
 74     Node* parent = root;
 75 
 76     //將str[i]插入到trie樹中
 77     while(str[i] != '\0')
 78     {
 79         //如果包含str[i]的分支存在,則新建此分支
 80         if(parent->char_arr[str[i] - 'a'] == NULL)
 81         {
 82             parent->char_arr[str[i] - 'a'] = new Node();
 83             //將父節(jié)點中的字符串添加到當(dāng)前節(jié)點的字符串中
 84             strcat(parent->char_arr[str[i] - 'a']->current_str, parent->current_str);
 85 
 86             char str_tmp[2];
 87             str_tmp[0] = str[i];
 88             str_tmp[1] = '\0';
 89 
 90             //將str[i]添加到當(dāng)前節(jié)點的字符串中
 91             strcat(parent->char_arr[str[i] - 'a']->current_str, str_tmp);
 92 
 93             parent = parent->char_arr[str[i] - 'a'];
 94         }
 95         else
 96         {
 97             parent = parent->char_arr[str[i] - 'a'];
 98         }
 99         i++;
100     }
101     parent->count++;
102 }
103 
104 //采用前序遍歷
105 void Trie::output(Node* &node, char** str, int& count)
106 {
107     if(node != NULL)
108     {
109         if(node->count != 0)
110         {
111             for(int i = 0; i < node->count; i++)
112                 str[count++] = node->current_str;
113         }
114         for(int i = 0; i < NUM; i++)
115         {
116             output(node->char_arr[i], str, count);
117         }
118 
119     }
120 }

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多