码迷,mamicode.com
首页 > 其他好文 > 详细

字典树(原创)

时间:2017-12-02 14:14:28      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:字典   style   strong   存在   节点   struct   div   查找树   aik   

1.概念

1.又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。

2.优点:

利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

3.基本性质:
a.根节点不包含任何字符,除根节点外每一个节点都只包含一个字符;
b.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 每个节点的所有子节点包含的字符都不相同。
c.字典树的节点并不真正存储该字符。
4.功能:
a.查找某单词
b.统计某单词出现的次数
c.对单词进行排序
d.删除(比较少用)
5.应用:
1.串的快速检索
给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。
在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。
2.“串”排序
给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序小到大输出
用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。
 

3.最长公共前缀

对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。
6.实现分析:
本文以都是小写字母为例,即该树有26个叉(后期丰富可以加上大写字母,规定字符等)
每一个节点都含有一个指针数组,每个指针数组里装26根指针,除了该指针数组之外,每个节点还应该有一个标志flag。
flag有以下作用:
a.初始为0,当当前节点是某个单词结尾的时候,flag加一,
b.同时flag也可以用来统计单词数
 
 
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 
  5 typedef struct node
  6 {
  7     int nFlag;
  8     struct node *pCharacter[26];
  9     char *str;//若某节点是某个单词的结尾,则把该单词保存在该节点中。
 10 }TrieTree;
 11 
 12 void AddWord(TrieTree *pTree,char *str)
 13 {
 14     int i;
 15     TrieTree *pTemp = NULL;
 16     for(i = 0;i<strlen(str);i++)
 17     {
 18         //节点的对应位置空 添加节点
 19         if(pTree->pCharacter[str[i]-97] == NULL)
 20         {
 21             pTemp = (TrieTree*)malloc(sizeof(TrieTree));
 22             memset(pTemp,0,sizeof(TrieTree));
 23 
 24             pTree->pCharacter[str[i]-97] = pTemp;
 25         }
 26 
 27         //向下走
 28         pTree = pTree->pCharacter[str[i]-97];
 29     }
 30 
 31     //末尾标记
 32     pTree->nFlag++;
 33     pTree->str = str;
 34 }
 35 
 36 
 37 TrieTree *CreateTrieTree(char *str[],int nLength)
 38 {
 39     if(str == NULL || nLength <=0)return NULL;
 40 
 41     TrieTree *pRoot = NULL;
 42     pRoot = (TrieTree*)malloc(sizeof(TrieTree));
 43     memset(pRoot,0,sizeof(TrieTree));
 44 
 45     //将字符串依次添加
 46     int i;
 47     for(i = 0;i<nLength;i++)
 48     {
 49         AddWord(pRoot,str[i]);
 50     }
 51     return pRoot;
 52 }
 53 
 54 void Search(TrieTree *pRoot,char *str)
 55 {
 56     if(str == NULL || pRoot == NULL)return;
 57 
 58     int i;
 59     for(i = 0;i<strlen(str);i++)
 60     {
 61         if(pRoot->pCharacter[str[i]-97] == NULL)
 62         {
 63             printf("failed.\n");
 64             return;
 65         }
 66         pRoot = pRoot->pCharacter[str[i]-97];
 67     }
 68     
 69     //检测末尾标志
 70     if(pRoot->nFlag != 0 )
 71     {
 72         printf("%s\n",pRoot->str);
 73         return;
 74     }
 75     else
 76     {
 77         printf("hhhh failed.\n");
 78         return;
 79     }
 80 }
 81 
 82 void Traversal(TrieTree *pTree)
 83 {
 84     if(pTree == NULL)
 85         return;
 86 
 87     if(pTree->nFlag != 0)
 88     {
 89         printf("%s\n",pTree->str);
 90     }
 91 
 92     int i;
 93     for(i = 0;i<26;i++)
 94     {
 95         Traversal(pTree->pCharacter[i]);
 96     }
 97 }
 98 
 99 int main()
100 {
101     char *str[] = {"app","apple","orange","lemon","logo","ball","tie","glory"};
102     TrieTree *pRoot = CreateTrieTree(str,8);
103     Traversal(pRoot);
104     printf("----------------------\n");
105     Search(pRoot,"ball");
106     return 0;
107 }

 

字典树(原创)

标签:字典   style   strong   存在   节点   struct   div   查找树   aik   

原文地址:http://www.cnblogs.com/curo0119/p/7953972.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!