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)就是就是应用这个算法。
#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)就是就是应用这个算法。
相关文章推荐
- 斐波那契序列 集锦 矩阵乘法
- C++ 运算符重载(1)
- 如何实现一个malloc
- 使用Memory Analyzer Tool(MAT)Eclipse插件分析内存泄露
- SQLiteOpenHelper数据库的创建or升级or增删改查
- Win10技巧:勾掉这几个选项更优体验win10
- CheungSSH国产自动化运维工具开源Web界面
- webservice SoapHeader 验证
- PHP判断字符串的包含
- HDU 2068 RPG的错排(错排公式 + 详解)
- LeetCode #33 Search in Rotated Sorted Array
- 计算字符个数(java)
- SSL与TLS 区别 以及介绍
- 4个值得注意的点(先记后写)
- easydialog.js
- 如何能够在Android运行Java的main方法
- Luci上增加本地ipk软件包安装功能
- LA3987 Ladies’ Choice 婚姻稳定算法
- VS2015编译boost1.58 Linux平台编译
- 【JavaScript】DOM总结