字典树

字典树能有效处理查询某个字符串出现的次数,创建树的时间复杂度为 O(n*len),其中n 为字符串的个数,len 为字符串的平均复杂度;

我的代码里空间复杂度并不算好,有很多空指针。但处理该类问的时间复杂度能比哈斯要好。

查询的时间复杂度为O(len)


代码如下:)

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

#define SIZE 26
#define CHECK_RET(ret,info) \
	if((ret) < 0) printf("error:%s\n",(info)),exit(EXIT_FAILURE)

typedef struct Trie{
	int cnt;// 该字符在该位置出现的次数
	int times;// 标识为词尾
	struct Trie * next[SIZE];
}*Trie, Node;

int initial(Node ** node)
{
	if((*node = malloc(sizeof(Node))) == NULL)
		return -1;

	(*node)->cnt = 1;
	(*node)->times = 0;
	for(int i=0; i<SIZE; i++)
		(*node)->next[i] = NULL;

	return 0;
}


int insert(Trie * tree2,char src[])
{
	Trie tree = *tree2; // 为再次插入做准备
	if(tree == NULL)// 空树,注意字典树的根不存放字符
	{
		CHECK_RET(initial(&tree),"not more memory");
		*tree2 = tree; // 这步很重要,要注意,目的是把tree2指向正确分配了空间的地方
	}

	int i=0;
	Node * node;
	while(src[i] != '\0')
	{
		int ch_to_index = src[i] - 'a';
		if(!(tree)->next[ch_to_index])// 未存在
		{
			CHECK_RET(initial(&node),"not more memory");
			(tree)->next[ch_to_index] = node;
		}else{// 存在
			(tree)->next[ch_to_index]->cnt += 1;
		}

		if(src[i+1] == '\0')
		{
			(tree)->next[ch_to_index]->times += 1;
			break;
		}

		(tree) = (tree)->next[ch_to_index];
		i++;
	}
}

int find(Trie tree, char target[])
{
	if(tree == NULL)
		return -1;

	int i=0; 
	while(target[i] != '\0')
	{
		int ch_to_index = target[i] - 'a';
		if(!tree->next[ch_to_index])
		{
			printf("%c appears %d times at this postition\n",target[i],0);
			return -1;
		}else{
			printf("%c appears %d times at this postition\n",target[i],tree->next[ch_to_index]->cnt);
			if(target[i+1] == '\0')
			{
				return tree->next[ch_to_index]->times;
			}
			tree = tree->next[ch_to_index];
			i++;
		}
	}
}

int main()
{
	char set[][10] = {"abc","abc","abcd","dbc","fdd"};
	Trie tree = NULL;
	printf("trie tree has:\n");
	for(int i=0; i<sizeof(set)/sizeof(set[0]); i++)
		printf("%s\n",set[i]),insert(&tree,set[i]);

	char target[10];
	printf("input target you want to find its times of apperance:\n");
	while(scanf("%s",target)!=EOF)
	{
		int cnt;
		CHECK_RET(cnt = find(tree,target),"Not found,bye :)");
		printf("%s Appears %d times\n",target,cnt);
		printf("input target you want to find its times of apperance:\n");
	}

	return 0;
}



你可能感兴趣的:(c,struct,tree,null,input,insert)