静态分布内存存储trie树

以POJ3630,HDU1671为例,

若用动态分布内存,在HDU就能过,Time为312ms,Memory为3712k

但在POJ为TLE

若用静态分布内存,在POJ 上的Time为141ms,Memory为2876k

在HDU上Time为62ms,Memory为2720k

静态内存代码如下:

/****

  poj 3630  Memory:2876k      Time:141MS    Codelength:786b

  这道题使用malloc运行时间长,因此不动态分布内存(指针),采用静态分布内存(数组)。

***/
#include<stdio.h>
struct node
{
	int cov,next[10];    //next数组存储1~9的数字
	void init()
	{
		for(int i=0;i<10;i++)    //初始化next
			next[i]=0;
		cov=0;
	}
}tree[100010];

int flag,p;

void creat(char *s)
{	
	int index=0;
	int t;
	while(*s)
	{
		t=*(s++)-'0';          
		if(tree[index].next[t]!=0)     //判断节点是否存在,tree[index].next[t]表示第index个节点对应的t节点
		{
			index=tree[index].next[t];      //存在,转移到下个节点
			if(*s=='\0'||tree[index].cov==1)     // 此时已经能判断s为前缀,直接跳出
			{
				flag=1;     
				return ;
			}
		}
		else      //  节点不存在,新开辟一个节点
		{
			tree[++p].init();    //初始化下一个
			tree[index].next[t]=p;    //p表示节点个数或者序数
			index=p;     //tree[p]表示第index个节点
		}
	}
	tree[index].cov=1;    //字符串结尾标记
}

int main()
{
	int t,n;
	char a[100000];
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		tree[p=0].init();    //初始化
		flag=0;
		while(n--)
		{
			scanf("%s",a);
			if(flag==0)   //  还未能判断是否为前缀,继续插入操作
				creat(a);
		}
		if(flag==0)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

动态内存代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node
{
	int cover,end;
	node *next[12];
}*trie;

int flag;
trie tree;

void creat(char *a)
{
	int len=strlen(a);
	if(len==0)      
		return ;
	int i,j;	
	trie current,temp;
	current=tree;	
	for(i=0;i<len;i++)
	{
		if(current->cover==-1)
		{
			flag=1;
			return ;
		}
		if(current->next[a[i]-'0']!=0)
		{
			current=current->next[a[i]-'0'];
			if(i==len-1)
			{			
				flag=1;
				return ;
			}
		}
		else
		{
			temp=(trie)malloc(sizeof(node));
			for(j=0;j<=10;j++)
				temp->next[j]=0;
			current->next[a[i]-'0']=temp;
			current=temp;
			current->cover=0;
		}
	}
	current->cover=-1;
}

void del (trie node)  //谨记 ! ! 释放内存
{	
	if(node==NULL)		
		return;
	for(int i=0;i!=10;++i)
	{
		if(node->next[i]!=NULL)
			del(node->next[i]); 
	} 
	free(node);
}

int main()
{
	int n,m,i;
	char a[11];
	scanf("%d",&n);
	while(n--)
	{
		flag=0;
		scanf("%d",&m);
		tree=(trie)malloc(sizeof(node));
		for(i=0;i<=10;i++)
			tree->next[i]=0;
		while(m)
		{
			scanf("%s",a);
			creat(a);
			if(flag==1)
				break;
			m--;
		}
		int t=m;
		for(i=1;i<t;i++)
		{
			scanf("%s",a);
		}
		if(flag==1)
			printf("NO\n");
		else
			printf("YES\n");
		del(tree);
	}
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值