`
shaojiashuai123456
  • 浏览: 257665 次
  • 性别: Icon_minigender_1
  • 来自: 吉林
社区版块
存档分类
最新评论

字典树 --c语言

 
阅读更多

(1)trie.h

 

#ifndef TRIE_H_
#define  TRIE_H_

typedef    struct word_trie_t word_trie_t;
typedef    enum bool bool;

enum bool
{
       false=0,
       true=1,
};

struct   word_trie_t
{
  bool (*insert)(word_trie_t  *this,char *str);
  bool (*find_word)(word_trie_t  *this,char *str); 
  int (*find_prefix)(word_trie_t  *this,char *str); 
  bool (*delete)(word_trie_t *this,char *str); 
  void (*destroy)(word_trie_t  *this);
};

word_trie_t  *word_trie_create();

#endif

 

(2)trie.c

 

#include "trie.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
//////////////////////
/*   字典树节点 */
//////////////////////
#define TRIE_NODE_MAX 26
typedef struct   trie_node_t trie_node_t;

/*字典树节点结构*/
struct trie_node_t
{
      int count;         //用来计算前缀数
    bool is_str;      //用来标识到此的字符串
    trie_node_t *word[TRIE_NODE_MAX];  //子节点指针
};

/*创建一个节点*/
trie_node_t* trie_node_create()
{
        trie_node_t* node=(trie_node_t *)malloc(sizeof(trie_node_t));
        memset(node,0,sizeof(trie_node_t));
        return node;
}

/*回收一个节点*/
void  trie_node_destroy(trie_node_t* node)
{
         free(node);    
}


///////////////////////////////////
/*   字典树对外接口实现 */
///////////////////////////////////
typedef struct   private_word_trie_t private_word_trie_t;
struct   private_word_trie_t
{
            word_trie_t public;  //对外接口
	     trie_node_t *root;   //字典树根
};

//插入一个字符串
bool insert(private_word_trie_t  *this,char *str)
{
          
          trie_node_t  *current=this->root;
	   int  word_pos;
	   //不断的循环插入,直到字符串结尾
          while(*str)
          {
                   word_pos=*str-'a';
		    //如果插入的分支为空,新建节点
		     if(current->word[word_pos]==NULL)
		     {
		              current->word[word_pos]=trie_node_create();
		     }
		     current=current->word[word_pos];
		     //节点索引值增加
		     current->count++; 
                   str++;
          }
	   //在最后一个节点标识为一个字符串
	   current->is_str=true;
	   return true;
}

//查找节点
bool find_word(private_word_trie_t  *this,char *str)
{
          trie_node_t  *current=this->root;
	   int  word_pos;
          while(*str)
          {
                   word_pos=*str-'a';
		     //如果分支为空,标识没有此字符串
		     if((current=current->word[word_pos])==NULL)
		     {
		              return false;
		     }
		     str++;
          }
	   return current->is_str;
}

//查找前缀数
int   find_prefix(private_word_trie_t  *this,char *str)
{
          trie_node_t  *current=this->root;
	   int  word_pos;
          while(*str)
          {
                   word_pos=*str-'a';
		     if((current=current->word[word_pos])==NULL)
		     {
		              return 0;
		     }
		     str++;
          }
	   return current->count;	  
}

//删除一个字符串
bool delete(private_word_trie_t *this,char *str)
{
         trie_node_t  *current=this->root;
	   int  word_pos;
	    trie_node_t  *del=NULL;
	   //第一步查找,如果是曾经插入的字符串,可以删除
          if(find_word(this,str))
          {
               //释放前缀数,如果索引值为0,可以回收节点
          	 while(*str)
         	 {
                   word_pos=*str-'a';
		     if(((current->word[word_pos])->count--)==0)
		     {
		             del=current->word[word_pos];
		             current->word[word_pos]=NULL;
			      str++;
			      break;
		     }
		     str++;
          	}
		 //释放下面的节点
		 if(del!=NULL)
		 {
		          
			 while(*str)
         	         {
                           word_pos=*str-'a';	
			      current=del;
			      del=current->word[word_pos];
			      trie_node_destroy(current);
			      str++;
          	        }
			 trie_node_destroy(del);
		  }
		  return true;
          }
	   else
	   {
	          return false;
	   }
}

//递归回收节点
void trie_destroy(trie_node_t *node)
{
         int i;
         for(i=0;i<TRIE_NODE_MAX;i++)
          {
                if(node->word[i]!=NULL)
                {
                       trie_destroy(node->word[i]);    
                }
        }
	 trie_node_destroy(node);
}

//销毁节点树
void destroy(private_word_trie_t  *this)
{
        trie_destroy(this->root);
	 free(this);
}

//创建字典树对象
word_trie_t  *word_trie_create()
{
     private_word_trie_t  *this=(private_word_trie_t  *)malloc(sizeof(private_word_trie_t));
	 this->public.insert=(bool (*)(word_trie_t  *,char *))insert;
	 this->public.find_word=(bool (*)(word_trie_t  *,char *))find_word;
	 this->public.find_prefix=(int (*)(word_trie_t  *,char *))find_prefix;
	 this->public.delete=(bool (*)(word_trie_t *,char *))delete;
	 this->public.destroy=(void (*)(word_trie_t  *))destroy;
	 this->root=trie_node_create();
     return &this->public;
}


int main()
{
       word_trie_t  *tree=word_trie_create();
	char str[100];
	while(gets(str)&&str[0])
	{
	        tree->insert(tree,str);
	}

	while(gets(str)&&str[0])
	{
	        printf("前缀:%d\n",tree->find_prefix(tree,str));
		 if(tree->find_word(tree,str))
		 {
		       printf("%s是插入的一个字符串\n",str);
		 }
		 else
		 {
		        printf("%s不是插入的一个字符串\n",str);
		 }
	}
	tree->destroy(tree);
	return 1;
}

 

分享到:
评论

相关推荐

    搜索树-字典查找树-单词频次-数据结构-C语言.rar

    学习数据结构搜索树时,写的两个例子,一个是字典查找树,即给定一个文本文件,根据该文件构造一颗查找树,查找效率为O(N),即将单次按字母进行类似路径的分割,因此查找速度很快。将该示例稍作修改,即可变为统计...

    字典树算法 c语言实现

    用C语言实现的字典树算法,用C语言实现的字典树算法。

    C语言字典树创建和搜索示例

    一种C语言字典树创建和搜索的示例,可以创建一种无论增加多少单词,搜索速度依然 = 该语言字母数 * 单词长度 的效率的存储结构。一个demo

    米哈游部分笔试题目-C语言方向.docx

    哈希表数据结构:哈希表是一种以键值对形式存储数据的数据结构,通过哈希函数将键映射到数组的特定位置...字典树(Trie)数据结构:字典树是一种多叉树结构,用于高效地存储和查找字符串集合,尤其适用于前缀匹配问题。

    c语言数据结构_之_树

    c语言数据结构_之_树

    字典树 高效查找 单词存储

    字典树 实现字典树的 插入操作 删除操作 查找操作 哈哈, 蛮小巧简单的一个东东, 但是直接用总比重新写好!

    C++词频统计,数据结构期末大作业,包含源码,附带思维导图讲解

    Trie树(字典树) 字典树又叫前缀树,是处理字符串常用的数据结构,最近和朋友一起粗略写了一下关于字典树的词频统计。 一、功能介绍 文件流读写单词; 将读到的单词插入树中; 打印树,打印出单词和个数以及词频;...

    字典树的基本知识及使用C语言的相关实现

    主要介绍了字典树的基本知识及使用C语言的相关实现,这也是ACM等计算机考试和竞赛题目的基本知识,需要的朋友可以参考下

    字典树应用,检索文本文件单词

    C语言编写的字典树基础应用,可遍历文本文件,查找单词出现次数,所在行数,位置等信息

    算法与数据结构:字典树用法(trie)

    字典树:又称为Trie,是一种用于快速检索的多叉树结构。

    C语言数据结构和排序查找算法程序

    自己整理的用C语言写的数据结构和排序查找算法。数据结构包括:栈,队列,两...算法包括:10个排序(冒泡,插入,选择,快排,归并,桶排,希尔等),5个插入(直接插入,哈希,对于KMP SUNDAY 字典树 可能整理的不全)

    C语言基础-实现的单线程高并发的网络基础库

    由C语言实现的基础库,提供的功能有: 基础库 co_vec 向量数组 co_dict 字典(哈希表),内部有一个链表用于遍历,使用它可以实现lrucache co_set 集合,内部由红黑树实现。 co_list 双向链表 co_queue 循环队列 co_...

    数据结构(C语言描述)

    7.1 字典 218 7.2 线性表描述 219 7.3 跳表描述 222 7.3.1 理想情况 222 7.3.2 插入和删除 223 7.3.3 级的分配 224 7.3.4 类SkipNode 224 7.3.5 类SkipList 225 7.3.6 复杂性 229 7.4 散列表描述 229 7.4.1 理想散列...

    二级C语言公共基础知识

    (10) 数据字典是各类数据描述的集合,它通常包括5个部分,即数据项、数据结构、数据流、______和处理过程。 答:数据存储 (11) 设一棵完全二*树共有500个结点,则在该二*树中有______个叶子结点。 答:250 (12) 在...

    C语言编写的二叉排序树的插入、删除

    用C语言编写的一个程序,实现功能为对输入文本文件“in.txt"中的英文单词按照字典顺序输出,并统计单词出现的次数。所涉及到的内容为二叉排序树的查询和插入。

    C语言实现英文文本词频统计

    这几天写了一个基于C语言对文本词频进行统计的程序,开发及调试环境:mac集成开发环境Xcode;测试文本,马丁.路德金的《I have a dream》原文演讲稿。 主要运行步骤: 1. 打开文本把文本内容读入流中并且开辟相应...

    quicknode:一个小型库,可使用BST(二进制搜索树)以C语言使用词典

    一个小型库,可使用BST(二进制搜索树)以C语言使用词典。 为什么使用二叉搜索树 如果您优先考虑订购,那么没有比这更好的选择了,因为它很快。 您可以在O(log n)中搜索,删除和插入节点,而不是使用耗时O(n)来...

    全国计算机等级考试二级C语言考试大纲.doc

    * 软件工程基础:软件工程基本概念、软件生命周期概念、软件工具与软件开发环境、结构化分析方法、数据流图、数据字典、软件需求规格说明书、结构化设计方法、总体设计与详细设计、软件测试的方法、白盒测试与黑盒...

    C语言应用经典例子(分析+实现+源程序)

    24点游戏、acm资料、爱因斯坦五五问题、线段树、字典树、野人过河问题。。。。(n多)的分析以及实现+源程序

Global site tag (gtag.js) - Google Analytics