字典树

字典树能有效处理查询某个字符串出现的次数,创建树的时间复杂度为 O(n*len),其中n 为字符串的个数,len 为字符串的平均复杂度;

我的代码里空间复杂度并不算好,有很多空指针。但处理该类问的时间复杂度能比哈斯要好。

查询的时间复杂度为O(len)


代码如下:)

#include <stdio.h> #include <stdlib.h> #define SIZE 26 #define CHECK_RET(ret,info) \ if((ret) < 0) printf("error:%s\n",(info)),exit(EXIT_FAILURE) typedef struct Trie{ int cnt;// 该字符在该位置出现的次数 int times;// 标识为词尾 struct Trie * next[SIZE]; }*Trie, Node; int initial(Node ** node) { if((*node = malloc(sizeof(Node))) == NULL) return -1; (*node)->cnt = 1; (*node)->times = 0; for(int i=0; i<SIZE; i++) (*node)->next[i] = NULL; return 0; } int insert(Trie * tree2,char src[]) { Trie tree = *tree2; // 为再次插入做准备 if(tree == NULL)// 空树,注意字典树的根不存放字符 { CHECK_RET(initial(&tree),"not more memory"); *tree2 = tree; // 这步很重要,要注意,目的是把tree2指向正确分配了空间的地方 } int i=0; Node * node; while(src[i] != '\0') { int ch_to_index = src[i] - 'a'; if(!(tree)->next[ch_to_index])// 未存在 { CHECK_RET(initial(&node),"not more memory"); (tree)->next[ch_to_index] = node; }else{// 存在 (tree)->next[ch_to_index]->cnt += 1; } if(src[i+1] == '\0') { (tree)->next[ch_to_index]->times += 1; break; } (tree) = (tree)->next[ch_to_index]; i++; } } int find(Trie tree, char target[]) { if(tree == NULL) return -1; int i=0; while(target[i] != '\0') { int ch_to_index = target[i] - 'a'; if(!tree->next[ch_to_index]) { printf("%c appears %d times at this postition\n",target[i],0); return -1; }else{ printf("%c appears %d times at this postition\n",target[i],tree->next[ch_to_index]->cnt); if(target[i+1] == '\0') { return tree->next[ch_to_index]->times; } tree = tree->next[ch_to_index]; i++; } } } int main() { char set[][10] = {"abc","abc","abcd","dbc","fdd"}; Trie tree = NULL; printf("trie tree has:\n"); for(int i=0; i<sizeof(set)/sizeof(set[0]); i++) printf("%s\n",set[i]),insert(&tree,set[i]); char target[10]; printf("input target you want to find its times of apperance:\n"); while(scanf("%s",target)!=EOF) { int cnt; CHECK_RET(cnt = find(tree,target),"Not found,bye :)"); printf("%s Appears %d times\n",target,cnt); printf("input target you want to find its times of apperance:\n"); } return 0; }


转载于:https://www.cnblogs.com/huangkq1989/archive/2011/10/06/2522614.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值