zoukankan      html  css  js  c++  java
  • 动态建树和静态建树 理解

    前言

    Trie树理解,该博客已经对Trie树进行了简要的介绍;

    Trie树分为静态建树和动态建树,两者的区别在于:

    • 插入操作时,静态建树中插入不存在的结点利用的是已经创建好的大数组进行存放,而动态数组则会动态申请一个结点;
    • 删除操作时,静态建树中删除只需将跟节点的next数组都置为空即可,而动态建树中则要递归删除已经分配的每一个结点;
    • 动态建树使用new费时,静态建树预存结点数据很费空间;

    静态建树

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // 数组个数
    #define Max 10000
    
    struct Tree_Node {
        bool end;
        int count; //记录访问某个字符串的个数
        struct Tree_Node * next[26];
        
    }node[Max];
    
    typedef struct Tree_Node * Node;
    
    // 输入字符串
    char input[12];
    
    // 静态建树的特点,记录用了几个Node,则下一个结点是node[move]
    int move = 0;
    
    void insert_heap(Node root) {
        Node pNode = root;
        char * tmp = input;
        
        while (*tmp != '') {
            int idx = *tmp - 'a';
            if (!pNode->next[idx]) {
                pNode->next[idx] = &node[move++];
                pNode->next[idx]->end = false;
                pNode->next[idx]->count = 0;
                memset(pNode->next[idx]->next, 0, sizeof(pNode->next[idx]->next));
            }
            tmp++;
            pNode = pNode->next[idx];
        }
        
        //访问结束
        pNode->end = true;
        pNode->count++;
    }
    
    void build_heap(Node root) {
        for (int i = 0; i < 12; ++i) {
            scanf("%s", input);
            insert_heap(root);
        }
    }
    
    void search_heap(Node root) {
        char *tmp = input;
        Node pNode = root;
        
        while (*tmp != '') {
            int idx = *tmp - 'a';
            
            if (!pNode->next[idx])
                break;
            
            tmp++;
            pNode = pNode->next[idx];
        }
        
        if (*tmp != '' || !pNode->end) {
            printf("no exist
    ");
        }
        else {
            printf("exist count :%d
    ", pNode->count);
        }
    }
    
    void delete_heap(Node root) {
        memset(root->next, 0, sizeof(root->next));
    }
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        Node root = &node[move++];
        memset(root->next, 0, sizeof(root->next));
        printf("input content
    ");
        
        build_heap(root);
        
        printf("get the result
    ");
        for (int i = 0; i < 12; ++i) {
            scanf("%s", input);
            search_heap(root);
        }
        
        delete_heap(root);
        
        return 0;
    }
    
    

    这里需要注意的地方在于全局维护一个move下标,增加新结点时要移动到下一位;

    动态建树

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define Max 1000000
    
    typedef struct Tree_Node {
        int count; //记录访问某个字符串的个数
        struct Tree_Node * next[26];
    }TNode,*Node;
    
    // 输入字符串
    char input[20];
    char output[20];
    
    void insert_heap(Node root) {
        Node pNode = root;
        char * in = input;
        
        while (*in != '') {
            int idx = *in - 'a';
            if (pNode->next[idx]) {
                pNode = pNode->next[idx];
            }
            else {
                pNode->next[idx] = (Node)malloc(sizeof(TNode));
                
                if (!pNode->next[idx]) {
                    printf("idx %d为空", idx);
                }
                for (int i = 0; i < 26; ++i) {
                    pNode->next[idx]->next[i] = NULL;
                }
                pNode->next[idx]->count = 0;
                pNode = pNode->next[idx];
            }
            
            in++;
        }
        
        //访问结束
        pNode->count++;
    }
    
    void build_heap(Node root) {
        for (int i = 0; i < 4; ++i) {
            scanf("%s", input);
            insert_heap(root);
        }
    }
    
    void search_heap(Node root) {
        char *tmp = output;
        Node pNode = root;
        
        while (*tmp != '') {
            int idx = *tmp - 'a';
            
            if (!pNode->next[idx])
                break;
            
            tmp++;
            pNode = pNode->next[idx];
        }
        
        if (*tmp != '' && pNode->count > 0) {
            printf("no exist
    ");
        }
        else {
            printf("exist count :%d
    ", pNode->count);
        }
    }
    
    // 释放子结点后,释放跟节点
    void delete_heap(Node node) {
        for (int i = 0; i < 26; ++i) {
            if (node->next[i]) {
                delete_heap(node->next[i]);
            }
        }
        free(node);
    }
    
    int main(int argc, const char * argv[]) {
        Node root = (Node)malloc(sizeof(TNode));
        for (int i = 0; i < 26; ++i) {
            root->next[i] = NULL;
        }
        root->count = 0;
        
        printf("input content
    ");
        
        build_heap(root);
        
        printf("get the result
    ");
        
        scanf("%s", output);
        
        search_heap(root);
        
        delete_heap(root);
        
        return 0;
    }
    
    

    这里需要注意的地方是,分配内存的时候不要弄成指针了,分配的应该是结构的内存大小;

  • 相关阅读:
    完爆!用边缘容器,竟能秒级实现团队七八人一周的工作量
    手把手教你使用 cert-manager 签发免费证书
    手把手教你使用 Nginx Ingress 实现金丝雀发布
    Codeforces 534B Covered Path 贪心
    Codeforces 534A Exam 水
    Topcoder open 2015 Round 1A 250 Similars 枚举 + 状压
    Topcoder SRM 654 DIV1 500 FoldingPaper2 递归 + 枚举
    Topcoder SRM655 DIV2 250 BichromeBoard 水
    2015 Google code jam Qualification Round B 枚举 + 贪心
    2015 Google code jam Qualification Round A 水
  • 原文地址:https://www.cnblogs.com/George1994/p/6346790.html
Copyright © 2011-2022 走看看