您的位置:首页 > 编程语言

hdoj 1671(trie树)(要清除动态内存,要不然的话就会mtl)(还有很重要的东西写在代码的最后注释当中)

2012-02-29 20:29 393 查看
#include <iostream>
using namespace std;

//定义一个结构体
typedef struct Trie{
int v;//表示这一层的元素个数,如果这一层为-1.表示没有元素
Trie *next[10];//下一个节点有10个
}Trie;

Trie *root;//声明一个根???????????????

void createTrie(char *str)
{
int len = strlen(str);

Trie *p = root, *q;//p表示游标

for(int i=0; i<len; ++i)
{
int id = str[i]-'0';//标号

//如果说下一个节点为空,那么新建一个trie树,接上去
if(p->next[id] == NULL)
{

//生成一个trie树
q = (Trie *)malloc(sizeof(Trie));
q->v = 1;

//把新树的其它节点都做成空
for(int j=0; j<10; ++j)
q->next[j] = NULL;

//接上数
p->next[id] = q;

//移动游标
p = p->next[id];
}

//如果说这个节点不是空,比如说119和110.当插入119以后,119都是1.
//当插入110的时候,v的值变为2.但是9和0都是1
else
{
p->next[id]->v++;
p = p->next[id];//移动游标
}
}

//最后一个节点定义为空。当插入113的时候,113都插入啦。让后3的下一个是-1
p->v = -1;
}

//这个find函数还有一点问题。
int findTrie(char *str)
{
int len = strlen(str);
Trie *p = root;//先把游标指向根节点

//一层一层的插入
for(int i=0; i<len; ++i)
{
int id = str[i]-'0';
p = p->next[id];

//如果说这一层是空,
if(p == NULL)
return 0;
if(p->v == -1)
return -1;
}
return -1;
}

int deal(Trie* T)
{//这是把T清空,一开始没加这个,结果MLE.
int i;
if(T==NULL)
return 0;
for(i=0;i<10;i++)
{
if(T->next[i]!=NULL)
deal(T->next[i]);
}
free(T);
return 0;
}

#define MAX 10005
//#define MAX 10

class Point
{
public:
char name[10];
int length;
};

Point point[MAX];

int compare(const void *a,const void *b)
{
return            ((Point*)b)->length-((Point*)a)->length;
}

int is(char *str)
{
int len = strlen(str);

Trie *p = root, *q;//p表示游标

for(int i=0; i<len; ++i)
{
int id = str[i]-'0';//标号

//如果说下一个节点值为空,表示不是前缀
if(p->next[id] == NULL)
{
return 1;//返回1表示不是前缀,可以继续插入
}

//如果说这个节点不是空,比如说119和110.当插入119以后,119都是1.
//当插入110的时候,v的值变为2.但是9和0都是1
//那么移动游标
else
{
p = p->next[id];//移动游标
}

}

return 0;//比如说插入11935,让后插入119,插入以后发现,所有的点都有啦,表示不可以在插入啦
}

int main()
{
//freopen("in.txt", "r", stdin);
int nCases, nNum;
int i;

scanf("%d", &nCases);
while(nCases--)
{

root = (Trie *) malloc (sizeof(Trie));//新建一个trie树。

//把数初始化
for(i=0; i<10; ++i)
root->next[i] = NULL;

//输入一个数字
scanf("%d", &nNum);
for(i=0; i<nNum; ++i)
{
scanf("%s", point[i].name);
point[i].length=strlen(point[i].name);
}
qsort(point,nNum,sizeof(Point),compare);

//开始处理
int flag=1;//表示可以

for(i=0;i<nNum;i++)
{
//如果说不是前缀,就插入
if(is(point[i].name))
{
createTrie(point[i].name);
}
//如果说是前缀,返回0
else
{
flag=0;
break;
}
}

if(flag==0)
printf("NO\n");
else
printf("YES\n");

//清除动态内存
deal(root);
}
return 0;
}
/*

1 例如911,最后一个1的exist的值是“f”(就是法文的符号)。
2 如果这个点没有元素就是0x00000000如果有元素就是0x2806e0;
3 当比赛的时候,最好看原版的东西。因为都没有经过修改
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐