手机号码查找算法(基数树)

44 篇文章 0 订阅
19 篇文章 0 订阅

#define DIGITTREE_NODE_COUNT    111111
typedef struct digittree_node digittree_node;
typedef struct digittree_tree digittree_tree;
struct digittree_node{
    digittree_node  *parent;
    digittree_node  *child[10];
    char    label;
    char    level;
    char    valid;
    void    *data;
};  
struct digittree_tree{
    int     nodes;
    pthread_mutex_t lock;
    digittree_node  *root;
};
#define UNUSE   0
#define INUSE   1

static int check_str_isdigit(char *str)
{
    int     i;
    assert(str != NULL);
    if(strlen(str) == 0 || strlen(str) > 20)
        return 0;
    for(i=0; str[i]!='\0'; i++){
        if(!isdigit(str[i]))
            return 0;
    }
    return 1;
}
static int check_node_unuse_isleaf(digittree_node *node)
{
    int     i;
    assert(node != NULL);
    if(node->valid == INUSE)
        return 0;
    for(i=0; i<10; i++){
        if(node->child[i] != NULL)
            return 0;
    }
    return 1;
}
int digittree_create(digittree_tree **tree)
{
    int    stat;
    digittree_node  *p;

    if(tree == NULL)
        return EINVAL;
    stat = com_mmap_create((void**)tree, sizeof(digittree_tree));
    if(0 != stat){
        log_error(com_mmap_create,stat);
        return stat;
    }
    //init tree
    (*tree)->nodes = 0;
    stat = com_lock_init(&(*tree)->lock, COM_LOCK_SHARE);
    if(0 != stat){
        log_error(pthread_mutex_init,stat);
        return stat;
    }
    //init root
    stat = com_mmap_create((void**)&p, sizeof(digittree_node));
    if(0 != stat){
        log_error(com_mmap_create,stat);
        return stat;
    }
    memset(p, 0, sizeof(digittree_node));
    (*tree)->root = p;
    return 0;
}
int digittree_find(digittree_tree *tree, char *str, void **data)
{
    int stat = 0;
    int i, j, find = COM_NOFOUND;
    digittree_node  *p = NULL;

    if(tree == NULL || str == NULL || data == NULL)
        return EINVAL;
    if(!check_str_isdigit(str))
        return EINVAL;
    p = tree->root;
    COM_LOCK(&tree->lock);
    for(i=0; str[i]!='\0'; i++, p=p->child[j]){
        j = str[i] - '0';
        if(p->child[j] ==NULL)
            break;
        if(p->child[j]->valid == INUSE){
            find = 0;
            (*data) = p->child[j]->data;
            break;
        }
    }
    COM_UNLOCK(&tree->lock);
    return find;
}
int digittree_add(digittree_tree *tree, char *str, void *data)
{
    int stat = 0;
    int i, j;
    digittree_node  *p, *pn;

    if(tree == NULL || str == NULL)
        return EINVAL;
    if(!check_str_isdigit(str))
        return EINVAL;
    p = tree->root;
    COM_LOCK(&tree->lock);
    stat = COM_NOFOUND;
    for(i=0; str[i]!='\0'; i++, p=p->child[j]){
        j = str[i] - '0';
        if(p->child[j] == NULL){
            stat = com_mmap_create((void**)&pn, sizeof(digittree_node));
            if(0 != stat){
                log_error(com_mmap_create,stat);
                break;
            }
            memset(pn, 0, sizeof(digittree_node));
            pn->parent = p;
            pn->label = j;
            pn->level = i+1;
            pn->data = data;
            p->child[j] = pn;
            tree->nodes++;
            log_printf("*** add:%d,%d ***\n", pn->level, pn->label);
        }
        if(str[i+1] == '\0'){
            if(p->child[j]->valid == INUSE){
                stat = COM_EXIST;
            }else{
                p->child[j]->valid = INUSE;
                stat = 0;
            }
            break;
        }
    }
    COM_UNLOCK(&tree->lock);
    return stat;
}
int digittree_del(digittree_tree *tree, char *str, void **data)
{
    int stat = 0;
    int i, j;
    digittree_node  *p, *pc;

    if(tree == NULL || str == NULL)
        return EINVAL;
    if(!check_str_isdigit(str))
        return EINVAL;
    p = tree->root;
    COM_LOCK(&tree->lock);
    stat = COM_NOFOUND;
    for(i=0; str[i]!='\0'; i++, p=p->child[j]){
        j = str[i] - '0';
        if(p->child[j] == NULL)
            break;
        if(str[i+1] == '\0'){
            if(p->child[j]->valid == INUSE){
                p->child[j]->valid = UNUSE;
                (*data) = p->child[j]->data;
                stat = 0;
                pc = p->child[j];
                while((pc!=tree->root) && check_node_unuse_isleaf(pc)){
                    p = pc->parent;
                    p->child[(int)pc->label] = NULL;
                    log_printf("*** del:%d,%d ***\n", pc->level, pc->label);
                    com_mmap_destroy(pc, sizeof(digittree_node));
                    tree->nodes--;
                    pc = p;
                }
            }
            break;
        }
    }
    COM_UNLOCK(&tree->lock);
    return stat;
}
static void travel_node(digittree_tree *tree, digittree_node *node)
{
    int     i, j, k;
    char    buf[22];
    char    buf2[22];
    digittree_node  *p = NULL;

    if(node->valid == INUSE){
        j = 0; p = node;
        while(p != tree->root){
            buf[j++] = '0'+p->label;
            p = p->parent;
        }
        k = 0; buf2[j] = '\0';
        while(--j >= 0)
            buf2[k++] = buf[j];
        log_printf("*** travel:%s ***\n", buf2);
    }
    for(i=0; i<10; i++){
        if(node->child[i] != NULL){
            travel_node(tree, node->child[i]);
        }
    }
}
int digittree_travel(digittree_tree *tree)
{
    int stat = 0;
    if(tree == NULL || tree->root == NULL)
        return EINVAL;
    COM_LOCK(&tree->lock);
    travel_node(tree, tree->root);
    COM_UNLOCK(&tree->lock);
    log_printf("*** travel nodes:%d\n", tree->nodes);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值