ternary searching tree三叉搜索树

#include 
#include 
#include 
#include 
#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(isplitchar > *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)就是就是应用这个算法。


你可能感兴趣的:(algo/data,struct)