您的位置:首页 > 其它

ternary searching tree三叉搜索树

2015-08-14 16:32 295 查看
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define log_warn printf

typedef struct tstree_node
{
struct tstree_node *left, *mid, *right;
char splitchar;
void *value;
}tstree_node_t;

typedef void (*tstree_traverse_cb)(void *);

/*
**@usage:recursively insert key/value pair
**@retval: root of a ternary seraching tree
*/
void tstree_insert_base(tstree_node_t *&root, tstree_node_t *&t, char *key, int len, void *value)
{
if(t == NULL)
{
t = (tstree_node_t *)calloc(1, sizeof(tstree_node_t));
t->splitchar = *key;

if(root == NULL)
{
root = t;
}
}

if(t->splitchar > *key)
{
tstree_insert_base(root, t->left, key, len, value);
}
else if(t->splitchar < *key)
{
tstree_insert_base(root, t->right, key, len, value);
}
else
{
if(len == 1)
{
if(t->value == NULL)
{
t->value = value;
}
else
{
log_warn("duplicated key. update value now.");
t->value = value;
}
}
else
{
tstree_insert_base(root, t->mid, ++key, --len, value);
}
}
}

void tstree_insert(tstree_node_t *&root, char *key, int len, void *value)
{
tstree_insert_base(root, root, key, len, value);
}

void tstree_traverse(tstree_node_t *node, tstree_traverse_cb cb)
{
if(!node) return;
if(node->left) tstree_traverse(node->left, cb);
if(node->right) tstree_traverse(node->right, cb);
if(node->mid) tstree_traverse(node->mid, cb);
if(node->value) cb(node->value);
}

void *tstree_search(tstree_node_t *node, char *key, int len)
{
int i = 0;
void *value = NULL;
while(i<len && node)
{
if(node->splitchar > *key) node = node->left;
else if(node->splitchar < *key) node = node->right;
else
{
i++;
value = node->value;
node = node->mid;
key++;
}
}

return i==len ? value : NULL;
}

void tstree_traverse_hndl(void *value)
{
fprintf(stderr, "%s\n", (char *)value);
}

#define mu_assert(e, msg) if(!(e)) fprintf(stderr, msg)
//construct a char array which trims the '\0' at tail
#define key_t(name, s) char __##name##_tmp__[] = {s}; char name[sizeof(__##name##_tmp__)-1];memcpy(name, __##name##_tmp__, sizeof(__##name##_tmp__)-1)

int main()
{
tstree_node_t *root = NULL;

key_t(test1, "TEST1");
key_t(test2, "TSTE");
key_t(test3, "TE");
key_t(test4, "TESTTT");

char *valueA = "valueA";
char *value2 = "value2";
char *value3 = "value3";
char *value4 = "value4";

{
tstree_insert(root, test1, sizeof(test1), valueA);
mu_assert(root != NULL, "Failed to insert into tst.\n");

tstree_insert(root, test2, sizeof(test2), value2);
mu_assert(root != NULL, "Failed to insert into tst with second name.\n");

tstree_insert(root, test3, sizeof(test3), value3);
mu_assert(root != NULL, "Failed to insert into tst with reverse name.\n");

tstree_insert(root, test4, sizeof(test4), value4);
mu_assert(root != NULL, "Failed to insert into tst with second name.\n");

//return NULL;
}

tstree_traverse(root, tstree_traverse_hndl);
char *s = (char *)tstree_search(root, test4, sizeof(test4));
fprintf(stderr, "key/value:TESTTT/%s\n", s);
s = (char *)tstree_search(root, test3, sizeof(test3));
fprintf(stderr, "key/value:TE/%s\n", s);
}


三叉搜索树结合了字典树的时间效率和二叉搜索树的空间效率优点。搜索引擎的搜索框的自动完成(auto complete)就是就是应用这个算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: