- 节点结构类型:int p; int e; Node* nexts[26];
- 是一棵多叉树,字符写在路上
- 对于一个字符串数组,遍历这个数组建树
- 每遇到一个字符串,遍历其字符,沿着树往下走,当前节点没有该字符的路就开一个新节点
- 填充我们的前缀树,在节点上添加信息
- p = pass,建树的过程中,经过这个节点几次
- e = end,当前有多少个字符串以这个节点结尾
- 所有字符串必然都经过头节点,所以头节点的p等于数组大小
- 前缀树的使用
- 查询一个特定的字符串出现了几次,沿着路走,读取e值
- 查询以特定字符串做前缀的字符串有多少,就是沿着路走,读取p值
- 这个结构比哈希表要强,可以计算前缀数量
- 我们说哈希表的操作是O(1),是认为单样本的大小无足轻重(非基础类型直接用内存地址,也可以忽略),但是当单样本长度很长,不能忽略这个时间,比如字符串算哈希值时间是O(字符串长度)
- 建前缀树的代价是O(M)M是总共的字符数
- 查一个字符串或者一个前缀的代价都是O(k)
- 第一种实现方法,
- 为每一个节点先准备26个节点的数组代表所有路,用其下方节点是否时空来代表路是否存在
- 建树的时候,在每一个节点处查完path,要走的时候,修改pass,如果一个字符串循环完了,当前节点修改end
- 删除比较麻烦,因为不想内存泄漏
- 删除操作指的时删除一个字符串的出现次数,就是在原数组中删掉这个字符串
- 如果这个字符串原来出现了多次,删除很简单,向下找路,减少p,末端减少e就好了
- 但是如果不再有这个字符串了,要删除多余的节点,防止内存泄漏(即p=0的节点)
- 第二种实现方式
- 路的表达不用节点数组而用一张哈希表,键是字符值,值是节点(一个加强的数组)
- 数组是一个最简单的哈希表,他的键是下标