【数据结构——树】Trie树的两种实现方式:二叉树(左孩子右兄弟)与二十六叉树

输入

输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示一个询问。

在20%的数据中n, m<=10,词典的字母表大小<=2.

在60%的数据中n, m<=1000,词典的字母表大小<=5.

在100%的数据中n, m<=100000,词典的字母表大小<=26.

输出

对于每一个询问,输出一个整数Ans,表示词典中以给出的字符串为前缀的单词的个数。

实现方式一:二叉树(左孩子右兄弟)

#include<iostream>
#include<string>
#include<malloc.h>
using namespace std;

struct node{
	char c;
	int count;
	node *next;
	node *right;
};

node* creat(void)
{
	node *p=(node*)malloc(sizeof(node*));
	p->count =0;
	p->next =NULL;
	p->right =NULL;
	p->c ='*';
	return p;
}

int main()
{
	int m,n,i,j=0,k=0,h=0;
	string s;
	node *root=creat();
	node *tmp;
	cin>>m;
	while(m--)
	{
		tmp=root;
		cin>>s;
		j=0;
		while(s[j]!='\0')
		{
			if(tmp->next ==NULL)
			{
				tmp->next =creat();
				tmp=tmp->next ;
				tmp->c =s[j];
				tmp->count ++;
			}
			else if(tmp->next ->c ==s[j])
			{
				tmp=tmp->next;
				tmp->count ++;
			}
			else if(tmp->next ->right ==NULL)
			{
				tmp->next ->right =creat();
				tmp=tmp->next ->right ;
				tmp->c =s[j];
				tmp->count ++;
			}
			else 
			{
				tmp=tmp->next ->right ;
				while((tmp->c !=s[j])&&(tmp->right !=NULL))
				{
					tmp=tmp->right ;
				}
				if(tmp->c ==s[j])
				{
					tmp->count ++;				
				}
				else
				{
					tmp->right =creat();
					tmp=tmp->right ;
					tmp->c =s[j];
					tmp->count ++;
				}
			}
			j++;
		}
	/*	
		node *rootp=root;
		while(rootp->next !=NULL)
		{
			rootp=rootp->next ;
			cout<<rootp->c;
		}
	*/
	}
	cin>>m;
	
	while(m--)
	{
		tmp=root;
		cin>>s;
		j=0;
		while(s[j]!='\0')
		{
			//cout<<tmp->c ;
			if(tmp->next ==NULL)
			{
				h=0;
				break;
			}
			else if(tmp->next ->c ==s[j])
			{
				h=1;
				tmp=tmp->next;
			}
			else if(tmp->next->right==NULL)
			{
				h=0;
				break;
			}
			else
			{
				tmp=tmp->next ->right ;
				while((tmp->c !=s[j])&&(tmp->right !=NULL))
				{
					tmp=tmp->right ;
				}
				if(tmp->c ==s[j])
				{
					h=1;	
				}
				else
				{
					h=0;
					break;
				}
			}
			j++;
		}
		if(h==0)
		{
			cout<<"0"<<endl;
		}
		else if(h==1)
		{
			cout<<tmp->count<<endl;
		}
	}
	return 0;
}

实现方法二:二十六叉树

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

const int branch = 26;

struct tnode
{
  int n;
  tnode* child[branch];	
};

long	n, m;
char	str[35];
char	base = 'a';
int		len;

tnode* create()
{
  tnode* tnew = (tnode*)malloc(sizeof(tnode));
  tnew->n = 0;
  for(int k=0; k<branch; k++)
    tnew->child[k] = NULL;
  return tnew;
}

int main()
{
  scanf("%ld", &n);
  tnode* root = create();
  root->n = -1;				// flag -1: root
  tnode* tmp = NULL;
  
  while(n--)
  {
    scanf("%s", str);
    len = strlen(str);
    tmp = root;
    for(int i=0; i<len; i++)
    {
      if(tmp->child[str[i]-base] == NULL)
      {
        tmp->child[str[i] - base] = create();
      }
      tmp->child[str[i]-base]->n++;
      tmp = tmp->child[str[i] - base];
    }
  }

  scanf("%ld", &m);
  while(m--)
  {
    scanf("%s", str);
    tmp = root;
    len = strlen(str);
    for(int j=0; j<len; j++)
    {
      tmp = tmp->child[str[j] - base];
      // if the predixs never appear
      if(tmp == NULL)
        break;
    }
    if(tmp == NULL)
      printf("0\n");
    else	
      printf("%d\n", tmp->n);
  }

  return 0;
}

通过运行对比可以发现使用二叉树的结构比使用二十六叉树省空间,但时间开销较大。

    原文作者:Trie树
    原文地址: https://blog.csdn.net/rootken/article/details/42815561
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞