• 微软原版系统

  • 一键重装系统

  • 纯净系统

  • 在线技术客服

魔法猪系统重装大师 一键在线制作启动 U 盘 PE 系统 用一键重装的魔法拯救失去灵魂的系统
当前位置:首页 > 教程 > 电脑教程

Trie树遍历如何加速?

时间:2015年04月02日 15:29:26    来源:魔法猪系统重装大师官网    人气:12010

 Trie树用来给字符串排序的时候有一个好处:边读边排序,但是读完之后要输出的时候麻烦来了。经过测试,用26W个word建立的Trie中,空白位是使用位的20倍左右,那么在Trie比较大的时候当然也就比较慢了。这篇文章讨论的优化主要是去避免访问这些空白位,实现方式无关(数组或指针?)。

  首先想到的一个方法是:在insert的时候顺便标记这个节点有哪些子节点。因为总共只有26种可能性,那么自然也就想到了用一个int作为flag,如果0位置1则表示有‘a’这个子节点。

  第一步(记录)完成了,下面我们来看如何来使用该记录?熟悉位移的同学可能已经想到:可以使用x&-x来计算出最低位为1的数。但是遗憾的是这个并不是我们想要的结果,因为得到的是2^N,我们想要的是这个N。好的,最笨的一种方法出来了:

  int t[] = new int[1<<26];

  t[1<<0] = 0.....

非常遗憾的是我们申请不了这么大的空间。那么,问题就是将一些离散的数通过数组建立映射关系,很自然地就会联想到Hash。怎么使用Hash呢?我尝试了一下,从2^0到2^26对29取余数为:

  1.2.4.8.16.3.6.12.24.19.9.18.7.14.28.27.25.21.13.26.23.17.5.10.20.11

没有看错,没有一个是相同的!这样的话就可以仅仅使用一个大小不到30的数组就可以搞定。同样遗憾的时候,这里用到了取余数的操作,要知道这个还算比较大的,可能一不小心就把我们辛辛苦苦省下来的时间又葬送掉了。那么有没有其他的方法呢?还是回到最笨的方法的思路上:

  如果我们申请不了int[1<<26],那申请int[1<<13]总是可以的吧?

为什么这么做呢?因为申请不了这么大的空间!这时候就把这个问题换成两半了,比如在节点I出的标志位flag:

  int lowHalf = flag&((1<<14)-1);

  int highHalf = (flag>>13)&((1<<14)-1);

  while(lowHalf > 0){

    int i = lowHalf&-lowHalf;

    int j = t[i];

    // do someting

  }

  while(highHalf > 0){

    int i = highHalf&-highHalf;

    int j = t[i]+13;

    // do someting

  }

和最笨的那种方法相比,只是多了一次操作而已。

  好了现在来看最后一种方法,就不多写了:

  switch(flag&-flag){

  case 1<<0:

  case 1<<1:

  case 1<<2:

  .....

  }

PS:直接用一个整数来表示:
没有子节点为:0
a节点为:1 << 0
b节点为:1 << 1
......
z节点为: 1 << 25

最后还需一位来表示是否单词 1 << 26,当然,如果没有子节点,自然是单词了。

判断是否有z节点只要 &(1<<25)就好

如果遍历,可以先 | 0 一下减少是最终节点的操作

Trie,树,遍历,如何,加速,Trie,树用,来给,字符串
栏目:电脑教程 阅读:1000 2023/12/27
Win7教程 更多>>
U盘教程 更多>>
Win10教程 更多>>
魔法猪学院 更多>>

Copyright © 2015-2023 魔法猪 魔法猪系统重装大师

本站发布的系统仅为个人学习测试使用,请在下载后24小时内删除,不得用于任何商业用途,否则后果自负,请支持购买微软正版软件。

在线客服 查看微信 返回顶部