zoukankan      html  css  js  c++  java
  • Trie 字典树

    字典树是哈希树的变种, 它采用公用前缀的方式来提高效率, 刚开始以为公用前缀, 空间会节省, 后来想想, 空间也不是节省, 因为每一个都有26个指针(这里假设都是小写字母的话), 不过他的时间复杂度是常数级的, 效率非常高, O(1)的复杂度, 它是典型的空间换时间, 他常用的功能是增删查, 其实删除并不算太常用, 增加和查找用的比较多点.具体的实现代码如下:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 //结构体里面可以灵活的加一些东西,根据功能来加
      5 typedef struct Node{
      6     int isWord;//标记是否到这里是个单词
      7     struct Node *next[26];//26个子孩子,
      8 }Node, *PNode;
      9 
     10 void add_word(PNode *root, char *word)//将指定单词添加到字典树
     11 {
     12     PNode node;
     13     int len = strlen(word);
     14     int i = 0;
     15     PNode ptr = *root;
     16     while(i < len)
     17     {
     18         if(ptr->next[word[i] - 'a'] == NULL)
     19         {
     20             node = (PNode)malloc(sizeof(Node));
     21             for(int j = 0; j < 26; j++)
     22             {
     23                 node->isWord = 0;
     24                 node->next[j] = NULL;
     25             }
     26             ptr->next[word[i] - 'a'] = node;
     27         }
     28         ptr = ptr->next[word[i] - 'a'];
     29         i++;
     30     }
     31     ptr->isWord = 1;//最后标记这个点是单词的结尾
     32 }
     33 
     34 void search_word(PNode root, char *word)//查找单词,递归方式
     35 {
     36     if(word[0] != '' && root->next[word[0] - 'a'] == NULL)
     37     {
     38         printf("No this word
    ");
     39         return;
     40     }
     41     if(word[0] == '')
     42     {
     43         if(root == NULL)
     44             printf("exist!
    ");
     45         else
     46         {
     47             if(root->isWord == 1)
     48                 printf("exist!
    ");
     49             else
     50                 printf("No this word
    ");
     51         }
     52         return;
     53     }
     54     search_word(root->next[word[0] - 'a'], word + 1);
     55 }
     56 //查找单词,非递归方式
     57 int search_words(PNode root, char *word)
     58 {
     59     int len = strlen(word);
     60     int i = 0;
     61     PNode ptr = root;
     62     while(i < len)
     63     {
     64         if(ptr->next[word[i] - 'a'] == NULL)
     65             return 0;
     66         ptr = ptr->next[word[i] - 'a'];
     67         i++;
     68     }
     69     if(ptr->isWord == 1)
     70         return 1;
     71     return 0;
     72 }
     73 //删除指定的单词,这里只是将它的标记设为0, 并没有真正意义上的删除
     74 void delete_word(PNode *root, char *word)
     75 {
     76     if(word[0] == '' && (*root) != NULL)
     77     {
     78         (*root)->isWord = 0;
     79         return;
     80     }
     81     if((*root) == NULL)
     82     {
     83         printf("No this word
    ");
     84         return;
     85     }
     86     delete_word(&(*root)->next[word[0] - 'a'], word + 1);
     87 }
     88 //删除整个字典树,真正的删除
     89 //如果要在函数里面调用此函数的时候,调用完之后如果还想创建树,要重新malloc根节点
     90 void delete_all(PNode root)
     91 {
     92     for(int i = 0; i < 26; i++)
     93     {
     94         if(root->next[i] != NULL)
     95             delete_all(root->next[i]);
     96     }
     97     free(root);
     98 }
     99 
    100 int main()
    101 {
    102     int choice;
    103     char str[100];
    104     PNode root = (PNode)malloc(sizeof(Node));
    105     root->isWord = 0;
    106     for(int i = 0; i < 26; i++)
    107         root->next[i] = NULL;
    108     do{
    109         //测试菜单
    110         printf("1. add word   2. search word   3. delete word   0. exit
    ");
    111         scanf("%d", &choice);
    112         switch(choice)
    113         {
    114         case 1:
    115             scanf("%s", str);
    116             add_word(&root, str);
    117             break;
    118         case 2:
    119             scanf("%s", str);
    120             if(search_words(root, str) == 1)
    121                 printf("exist
    ");
    122             else
    123                 printf("not found
    ");
    124             //当然也可以用递归的那个
    125 //            search_word(root, str);
    126             break;
    127         case 3:
    128             scanf("%s", str);
    129             delete_word(&root, str);
    130         default:
    131             break;
    132         }
    133     }while(choice != 0);
    134     delete_all(root);
    135     return 0;
    136 }
  • 相关阅读:
    路由交换03-----传输层协议
    Linux结构目录
    Linux RedHat 7 配置本地 YUM源
    HUAWEI,H3C 三层交换机 常用命令
    windows操作系统更改 <远程桌面> 端口号
    SpringBoot 2.x (2):请求和传参
    SpringBoot 2.x (1):手动创建项目与自动创建项目
    Eclipse中使用Maven搭建SSM框架
    基于Spring和Mybatis拦截器实现数据库操作读写分离
    WinServer配置MySQL主从同步
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4027054.html
Copyright © 2011-2022 走看看