bitwise trie tree 的参考实现-nedtries简单解析

trie tree 是一种公共前缀树,(和关联规则的一种算法frequent-pattern growth算法的数据结构相同),具体定义见wiki。


上面为一棵trie tree,直观上看,如这种数据结构做索引,应该不错,事实也是如此:)。

节点值为0/1的trie tree,称为bitwise trie。bitwise trie是一个二叉查找trie tree。

下面看nedtrie 的实现。

首先看一下基本用法(code segment in test.c)

//define tree node struct
typedef struct foo_s foo_t;
struct foo_s {
  NEDTRIE_ENTRY(foo_s) link;
  size_t key;
};

//initial tree root
typedef struct foo_tree_s foo_tree_t;
NEDTRIE_HEAD(foo_tree_s, foo_s);
static foo_tree_t footree;

size_t fookeyfunct(const foo_t *r)
{
  return r->key;
}

NEDTRIE_GENERATE(static, foo_tree_s, foo_s, link, fookeyfunct, NEDTRIE_NOBBLEZEROS(foo_tree_s))

int main(void)
{
  foo_t a, b, c, *r;

  NEDTRIE_INIT(&footree);
  a.key=2;
  NEDTRIE_INSERT(foo_tree_s, &footree, &a);
  b.key=6;
  NEDTRIE_INSERT(foo_tree_s, &footree, &b);
  r=NEDTRIE_FIND(foo_tree_s, &footree, &b);
  assert(r==&b);
  c.key=5;
  r=NEDTRIE_NFIND(foo_tree_s, &footree, &c);
  assert(r==&b); /* NFIND finds next largest. Invert the key function (i.e. 1-key) to find next smallest. */
  NEDTRIE_REMOVE(foo_tree_s, &footree, &a);
  NEDTRIE_FOREACH(r, foo_tree_s, &footree)
  {
    printf("%p, %u\n", (void *) r, (unsigned) r->key);
  }


可以看出,nedtrie的功能相当于哈希树,将数据的哈希值作为键值,键值为整数,其二进制形式即为该数据的存储路径。如:hash("hello world") = 1111b,那么"hello world"在nedtrie上的存储路径即为root-1-1-1-1-value

和很多C的数据结构一样,作者使用宏实现了范型,支持多种数据类型。struct foo_s 为trie的内部节点和叶子节点数据类型,其中NEDTRIE_ENTRY为

#define NEDTRIE_ENTRY(type) \
struct {                   \
  struct type *trie_parent;           /* parent element */              \
  struct type *trie_child[2];         /* my children based on whether they are zero or one. */          \
  struct type *trie_prev, *trie_next; /* my siblings of identical key to me. */    \
}

其中数据存储在由trie_prev和trie_next组成的双向环形列表里。

foo_tree_s定义了跟节点的数据类型,NEDTRIE_HEAD定义了其结构,代码如下

#define NEDTRIE_HEAD2(name, type) \
struct name {                    \
  size_t count;                  \
  type *triebins[NEDTRIE_INDEXBINS]; /* each containing (1<<x)<=bitscanrev(x)<(1<<(x+1)) */ \
  int nobbledir;                 \
}
#define NEDTRIE_HEAD(name, type) NEDTRIE_HEAD2(name, struct type)

其中count为容器中元素的个数,tirebins为根节点的子树集, 根据存储元素的键值的最高非零位的位置将元素存储在不同的桶中,最高非0位的位置可由函数_BitScanReverse获取。



你可能感兴趣的:(bitwise trie tree 的参考实现-nedtries简单解析)