#include <stdio.h>
#include <stdlib.h>
#include <string.h>
////////////////////////////////////////////////////
//config
#define TSTRIE_NULL (0)
#define TSTRIE_SUCCESS (0)
#define TSTRIE_FAIL (-1)
#define TSTRIE_DELNODE(curNode) do{\
if(curNode->cur_property) \
free(curNode->cur_property); \
free(curNode); \
}while(0)
/////////////////////////////////////////////////////
//struct define
enum{
TERNARY_LEFT = 0,
TERNARY_MIDDLE,
TERNARY_RIGHT
};
typedef struct _TERNARY_TRIE_
{
char cur_data;
//呵呵,浪费几个字节,惭愧啊
char *cur_property;
/*
采用数组存放三叉指针:
0---左子树
1---中间子树
2---右子树
*/
struct _TERNARY_TRIE_ *child_trie[3];
struct _TERNARY_TRIE_ *parent;
//父结点
}TERNARY_TRIE;
/*构建树根指针,赋值-1
万物起始为-1,此节点仅仅是形式,完全不需要存值。
*/
void *tstrie_create()
{
TERNARY_TRIE *me = TSTRIE_NULL;
if(TSTRIE_NULL == (me = (TERNARY_TRIE *)malloc(sizeof(TERNARY_TRIE))))
return me;
memset(me, 0, sizeof(TERNARY_TRIE));
me->cur_data = -1;
return me;
}
void tstrie_destroy(void *root)
{
TERNARY_TRIE *me = (TERNARY_TRIE *)root;
TERNARY_TRIE *preNode = 0, *curNode = 0;
preNode = curNode = me->child_trie[TERNARY_MIDDLE];
while(curNode)
{
while(curNode->child_trie[TERNARY_LEFT])curNode = curNode->child_trie[TERNARY_LEFT];
if(curNode->child_trie[TERNARY_MIDDLE])
curNode = curNode->child_trie[TERNARY_MIDDLE];
else if(curNode->child_trie[TERNARY_RIGHT])
curNode = curNode->child_trie[TERNARY_RIGHT];
else
{
preNode = curNode->parent;
if(preNode)
{
if(preNode->child_trie[TERNARY_LEFT] == curNode)
preNode->child_trie[TERNARY_LEFT] = 0;
else if(preNode->child_trie[TERNARY_MIDDLE] == curNode)
preNode->child_trie[TERNARY_MIDDLE] = 0;
else if(preNode->child_trie[TERNARY_RIGHT] == curNode)
preNode->child_trie[TERNARY_RIGHT] = 0;
}
TSTRIE_DELNODE(curNode);
curNode = preNode;
}
}
}
int tstrie_addData(void *root, char *cur_data, char *prop)
{
TERNARY_TRIE *tmpNode = 0, *curNode = 0, *preNode = 0, *strNode = 0;
TERNARY_TRIE *me = 0;
unsigned char *cur_p = cur_data, *cur_prop = 0;
int ret = -1;
me = (TERNARY_TRIE *)root;
if(TSTRIE_NULL == me)
return -1;
preNode = curNode = me->child_trie[TERNARY_MIDDLE];
while(curNode)
{
if(*cur_p == 0)
{
break;
}
preNode = curNode;
ret = (*cur_p - curNode->cur_data);
if(0 != ret)
ret = (ret > 0)?1:-1;
else
cur_p++;
curNode = curNode->child_trie[ret + 1];
}
curNode = preNode;
preNode = TSTRIE_NULL;
strNode = TSTRIE_NULL;
while(*cur_p)
{
tmpNode = (TERNARY_TRIE *)malloc(sizeof(TERNARY_TRIE));
if(0 == tmpNode)
break;
memset(tmpNode, 0, sizeof(TERNARY_TRIE));
tmpNode->cur_data = *cur_p;
if(0 != preNode)
{
tmpNode->parent = preNode;
preNode->child_trie[TERNARY_MIDDLE] = tmpNode;
}
preNode = tmpNode;
if(0 == strNode)
strNode = tmpNode;
cur_p++;
}
if((prop) && (strlen(prop)))
{
cur_prop = (char *)malloc((strlen(prop) + 4) >> 2 << 2);
if(cur_prop)
{
memset(cur_prop, 0, (strlen(prop) + 4) >> 2 << 2);
strcpy(cur_prop, prop);
}
}
if(preNode)
{
preNode->cur_property = cur_prop;
}
else
{
if(curNode)
{
curNode->cur_property = cur_prop;
}
else
free(curNode);
}
if(TSTRIE_NULL == curNode)
{
curNode = me;
curNode->child_trie[TERNARY_MIDDLE] = strNode;
}
else
curNode->child_trie[ret + 1] = strNode;
if(0 != strNode)
strNode->parent = curNode;
return TSTRIE_SUCCESS;
}
int tstrie_delData(void *root, unsigned char *cur_data)
{
TERNARY_TRIE *curNode = 0, *preNode = 0;
TERNARY_TRIE *me = (TERNARY_TRIE *)root;
int ret = -1;
unsigned char *cur_p = cur_data;
if(TSTRIE_NULL == me)
return -1;
curNode = me->child_trie[TERNARY_MIDDLE];
while((curNode) && (*cur_p))
{
ret = (*cur_p - curNode->cur_data);
if(0 != ret)
ret = (ret > 0)?1:-1;
else
cur_p++;
preNode = curNode;
curNode = curNode->child_trie[ret + 1];
}
curNode = preNode;
if(*cur_p)
return TSTRIE_FAIL;
else
{
preNode = preNode->parent;
if(curNode->cur_property)
{
free(curNode->cur_property);
curNode->cur_property = 0;
}
while((0 == curNode->child_trie[TERNARY_LEFT])
&& (0 == curNode->child_trie[TERNARY_MIDDLE])
&& (0 == curNode->child_trie[TERNARY_RIGHT])
&& (0 == curNode->cur_property))
{
if(me == preNode)
{
TSTRIE_DELNODE(curNode);
me->child_trie[TERNARY_MIDDLE] = 0;
break;
}
else
{
TSTRIE_DELNODE(curNode);
if(preNode->child_trie[TERNARY_MIDDLE] == curNode)
{
preNode->child_trie[TERNARY_MIDDLE] = 0;
curNode = preNode;
preNode = preNode->parent;
}
else
{
if(preNode->child_trie[TERNARY_LEFT] == curNode)
preNode->child_trie[TERNARY_LEFT] = 0;
else if(preNode->child_trie[TERNARY_RIGHT] == curNode)
preNode->child_trie[TERNARY_RIGHT] = 0;
break;
}
}
}
return TSTRIE_SUCCESS;
}
}
char *tstrie_searchData(void *root, unsigned char *cur_data)
{
TERNARY_TRIE *curNode = 0, *preNode = 0;
TERNARY_TRIE *me = (TERNARY_TRIE *)root;
int ret = -1;
unsigned char *cur_p = cur_data;
if(TSTRIE_NULL == me)
return TSTRIE_NULL;
curNode = me->child_trie[TERNARY_MIDDLE];
while(curNode)
{
preNode = curNode;
ret = (*cur_p - curNode->cur_data);
if(0 != ret)
ret = (ret > 0)?1:-1;
else
cur_p++;
curNode = curNode->child_trie[ret + 1];
}
curNode = preNode;
if(0 == *cur_p)
{
return curNode->cur_property;
}
return TSTRIE_NULL;
}
char *testStr[7] = {
"zhong",
"hua",
"ren",
"min",
"gong",
"he",
"guo"
};
int main()
{
void *cur_root = 0;
char *prop_p = 0;
int i = 0;
cur_root = tstrie_create();
if(0 == cur_root)
return -1;
for(i = 0; i < 7; i++)
{
tstrie_addData(cur_root, testStr[i], testStr[i]);
}
for(i = 0; i < 7; i++)
{
prop_p = tstrie_searchData(cur_root, testStr[i]);
if(TSTRIE_NULL == prop_p)
printf("Search fail...\n");
else
printf("The word %s property is:\n %s\n", testStr[i], prop_p);
}
tstrie_delData(cur_root, testStr[3]);
for(i = 0; i < 7; i++)
{
prop_p = tstrie_searchData(cur_root, testStr[i]);
if(TSTRIE_NULL == prop_p)
printf("Search fail...\n");
else
printf("The word %s property is:\n %s\n", testStr[i], prop_p);
}
return 0;
}
[
本帖最后由 silent_world 于 2012-8-6 18:39 编辑 ]