字典树问题

/*
 * prot.c
 *
 * A try of implementing the Trie trees.
 *
 * Copyright (C) 2012-10-19 liutos <mat.liutos@gmail.com>
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

enum BOOL {
    TRUE,
    FALSE,
};
typedef struct trieNode {
    int value;
    char key;
    enum BOOL is_used;
    struct trieNode *child;
    struct trieNode *brother;
    struct trieNode *parent;
} *Trie, *TrieNode;

int (*value_modifier)(int, int);

TrieNode make_trie_node(char key, int value, enum BOOL is_used)
{
    TrieNode node = malloc(sizeof(struct trieNode));

    node->key = key;
    node->is_used = is_used;
    node->value = value;
    node->parent = node->child = node->brother = NULL;

    return node;
}

//生成树:每个节点:value:0;is_userd:false;
Trie make_init_trie(char *whole_key, int value)
{	
	//为空节点或者地址为'\0',返回NULL
    if (NULL == whole_key ||
        '\0' == *whole_key)
        return NULL;
    //第二个字符串的值为'\0'
    else if ('\0' == whole_key[1])
        return make_trie_node(whole_key[0], value, TRUE);
    else {
        TrieNode root = make_trie_node(whole_key[0], 0, FALSE);

        root->child = make_init_trie(whole_key + 1, value);
        if (root->child != NULL)
            root->child->parent = root;

        return root;
    }
}

char *make_node_label(TrieNode node)
{
    char *label = malloc(100 * sizeof(char));

    sprintf(label, "<c>|{key: %c| value: %d}|<b>",
            node->key, TRUE == node->is_used? node->value: 0);

    return label;
}

//递归打印树节点
void print_trie_core(Trie tree, FILE *fp)
{
    if (NULL == tree)
        return;
    fprintf(fp, "\tnode%p [label = \"%s\"];\n",
            tree, make_node_label(tree));
    if (tree->child != NULL) {
        print_trie_core(tree->child, fp);
        fprintf(fp, "\tnode%p:c -> node%p;\n",
                tree, tree->child);
    }
    if (tree->brother != NULL) {
        print_trie_core(tree->brother, fp);
        fprintf(fp, "\tnode%p:b -> node%p;\n",
                tree, tree->brother);
    }
}

void print_trie_compile(Trie tree)
{
    FILE *fp = fopen("trie.dot", "w");

    if (NULL == fp) {
        printf("Can not open file `trie.dot'.\n");
        exit(1);
    }
    fprintf(fp, "digraph G {\n\tnode [shape = record];\n");
    print_trie_core(tree, fp);
    fprintf(fp, "}");
}

int modify_value(int old_value, int new_value)
{
    return old_value + 1;
}

Trie insert_core(char *whole_key, int value, Trie tree)
{
	//空树时初始化
    if (NULL == tree || '\0' == *whole_key)
        return make_init_trie(whole_key, value);
    if ('\0' == whole_key[1] && whole_key[0] == tree->key) {
        if (TRUE == tree->is_used) {
            printf("The value of the node with key %c increasing.\n", tree->key);
            tree->value = value_modifier(tree->value, value);
        } else {
            tree->is_used = TRUE;
            tree->value = value;
        }

        return tree;
    }
    if (whole_key[0] == tree->key) {
        tree->child = insert_core(whole_key + 1, value, tree->child);
        if (tree->child != NULL)
            tree->child->parent = tree;
    } else {
        tree->brother = insert_core(whole_key, value, tree->brother);
        if (tree->brother != NULL)
            tree->brother->parent = tree;
    }

    return tree;
}

Trie insert_string_int(char *whole_key, int value, Trie tree)
{
    return insert_core(whole_key, value, tree);
}

char **read_ips(void)
{
    FILE *fp;
    char **ips = malloc(40 * sizeof(char *));
    int i;

    if (NULL == (fp = fopen("ips.txt", "r"))) {
        printf("Can not read file `ips.txt'.\n");
        exit(1);
    }
    for (i = 0; i < 40; i++) {
        char *line = malloc(20 * sizeof(char));
        size_t n = 20;
        int tmp;
        tmp = getline(&line, &n, fp);
        if ('\n' == line[tmp - 1])
            line[tmp - 1] = '\0';
        ips[i] = line;
    }

    return ips;
}

TrieNode find_max_value(Trie tree)
{
    return NULL;
}

int main(int argc, char *argv[])
{
    Trie tree = NULL;
    int i;
    /* int len = 40; */
    /* char **keys = read_ips(); */
    char *keys[] = {
        "abc",
        "b",
        "abd",
        "bcd",
        "abcd",
        "efg",
        "hii",
    };
    int len = sizeof(keys) / sizeof(char *);

    value_modifier = modify_value;
    for (i = 0; i < len; i++)
        tree = insert_string_int(keys[i], 1, tree);
    print_trie_compile(tree);

    return 0;
}


代码来源:https://github.com/Liutos/CLab/tree/master/trie代码


温习知识点:

1、枚举写法:

enum Tag{}

2、结构体常用写法:利用typeof关键字
typeof struct TagName{}*pointer;

3、函数指针用法:int (*value_modifier)(int, int);

4、C过程式编程,必须遵守先声明后使用

5、递归遍历树:要有结束递归的条件

比如:



//递归打印树节点
void print_trie_core(Trie tree, FILE *fp)
{
    if (NULL == tree)//结束条件
        return;
    fprintf(fp, "\tnode%p [label = \"%s\"];\n",
            tree, make_node_label(tree));
    if (tree->child != NULL) {
        print_trie_core(tree->child, fp);
        fprintf(fp, "\tnode%p:c -> node%p;\n",
                tree, tree->child);
    }
    if (tree->brother != NULL) {
        print_trie_core(tree->brother, fp);
        fprintf(fp, "\tnode%p:b -> node%p;\n",
                tree, tree->brother);
    }
}


6、写入字符串

sprintf([char *],"[格式控制]",[参数])

写入文件:

fprintf([FILE *],"[格式控制]",[参数]);

7、打开文件

FILE *fp = fopen("[文件地址]","[读写方式]");

8、指向指针的指针:

 char **ips = malloc(40 * sizeof(char *));

9、字符指针数组:

char *keys[] = {
        "abc",
        "b",
        "abd",
        "bcd",
        "abcd",
        "efg",
        "hii",
    }


keys指向一个数组,该数组存放指向字符串的指针(char *类型)。



对字典树不是很清楚。代码有些地方没有深入研究。


其中还涉及到Makefile文件的写法,make命令的使用。有待研究。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值