09btree

09btree/btree.c

#include <stdio.h>
#include "btree.h"
#include "queue.h"

static void bnode_init(struct btree_info *info,
        struct bnode_info *bnode)
{
    bnode->parent = NULL;
    bnode->lchild = NULL;
    bnode->rchild = NULL;
}

static void btree_add(struct btree_info *info,
        struct bnode_info *bnode,
        int (*cmp)(struct bnode_info *,
            struct bnode_info *)) 
{
    bnode_init(info, bnode);

    struct bnode_info *cur = info->root;
    struct bnode_info **pparent = &info->root;

    while (*pparent) {
        if (cmp(bnode, cur) < 0) {
            pparent = &cur->lchild;
        } else {
            pparent = &cur->rchild;
        }   

        if (*pparent) {
            cur = *pparent;
        }   
    }   

    *pparent = bnode;
    bnode->parent = cur;
}


09btree/Makefile

SRCS := btree.c
SUBDIR := 

$(BUILT_IN): $(SRCS:.c=.o) $(SUBDIR)
    $(LD) $(LDFLAGS) -r -o $@ $(SRCS:.c=.o) $(SUBDIR:=/$(BUILT_IN))

$(SUBDIR):
    $(MAKE) -C $@

$(SRCS:.c=.o):
    $(CC) $(CFLAGS) -c $<

$(DEP): $(SRCS)
    $(CC) $(CFLAGS) -MM $(SRCS) >$@
    sed -i "s/: / $@: /g" $@

sinclude $(DEP)

.PHONY: clean $(SUBDIR)

clean:
    for dir in $(SUBDIR); do \
        $(MAKE) -C $$dir clean; \
    done
    $(RM) $(SRCS:.c=.o) $(BUILT_IN) $(DEP)


09btree/include/btree.h

struct bnode_info {
    struct bnode_info *parent;
    struct bnode_info *lchild;
    struct bnode_info *rchild;
};

struct btree_info {
    struct bnode_info *root;
    void (*bnode_init)(struct btree_info *,
            struct bnode_info *);
    void (*add)(struct btree_info *,
            struct bnode_info *bnode,
            int (*cmp)(struct bnode_info *,
                struct bnode_info *));
    void (*preorder)(struct btree_info *,
            void (*)(struct btree_info *,
                struct bnode_info *));
    void (*inorder)(struct btree_info *,
            void (*)(struct btree_info *,
                struct bnode_info *));
    void (*postorder)(struct btree_info *,
            void (*)(struct btree_info *,
                struct bnode_info *));
    void (*levelorder)(struct btree_info *,
            void (*)(struct btree_info *,
                struct bnode_info *));
    void (*reverse)(struct btree_info *); 
    void (*del)(struct btree_info *,
            struct bnode_info *,
            void (*)(struct btree_info *,
                struct bnode_info *));


 

    struct bnode_info *(*search)(struct btree_info *,
            struct bnode_info *key,
            int (*cmp)(struct bnode_info *,
                struct bnode_info *));
};

void btree_init(struct btree_info *);
void btree_destroy(struct btree_info *,
        void (*)(struct btree_info *,
            struct bnode_info *));

#define offsetof(type, member) \
    ( (size_t)(&((type*)0)->member) )

#define container_of(ptr, type, member) \
    ({const typeof(((type*)0)->member) *__mptr = ptr; \
      (type *)((char*)ptr - offsetof(type, member));})


 


09btree/include/list.h

struct node_info {
    struct node_info *prev;
    struct node_info *next;
    char priv[];
};

struct list_info {
    struct node_info *head;
    void (*add)(struct list_info *,
            const void *data_entry,
            size_t data_size);
    void (*add_tail)(struct list_info *,
            const void *data_entry,
            size_t data_size);
    void (*del)(struct list_info *,
            struct node_info *,
            size_t data_size);
};

#define list_for_each(cur, head) \
    for (cur = (head)->next; \
        (cur) != (head); \
        cur = (cur)->next)

#define list_for_each_safe(cur, tmp, head) \
    for (cur = (head)->next, tmp = (cur)->next; \
        (cur) != (head); \
        cur = tmp, tmp = (tmp)->next)

#define ENTRY(node, type) ((type*)(node->priv))

void list_init(struct list_info*);
void list_destroy(struct list_info*);


09btree/include/queue.h

#include "list.h"

struct queue_info {
    struct list_info list;
    void (*push)(struct queue_info *,
            const void *data_entry,
            size_t data_size);
    int (*pop)(struct queue_info *,
            void *data_entry,
            size_t data_size);
    int (*top)(struct queue_info *,
            void *data_entry,
            size_t data_size);
    int (*isempty)(struct queue_info *); 
};

void queue_init(struct queue_info *); 
void queue_destroy(struct queue_info *); 
~                                                


09btree/main/test.c

#include <stdio.h>
#include <stdlib.h>
#include "btree.h"

struct node_info {
    ssize_t data;
    struct bnode_info bnode;
};

static int cmp(struct bnode_info *a, struct bnode_info *b)
{
    struct node_info *pa = container_of(a, struct node_info, bnode);
    struct node_info *pb = container_of(b, struct node_info, bnode);

    return pa->data - pb->data;
}

static void print_node(struct btree_info *info,
        struct bnode_info *bnode)
{
    struct node_info *ptr = container_of(bnode, struct node_info, bnode);
    printf("%ld ", ptr->data);
}

static void m_free(struct btree_info *info,
        struct bnode_info *bnode)
{
    info->bnode_init(info, bnode);
    free(container_of(bnode, struct node_info, bnode));
}


 

int main()
{
    struct btree_info btree;
    btree_init(&btree);

    struct node_info *cur = NULL;

    ssize_t s[] = {10, 15, 2, 6, 7, 3, 8, 5, 2, 0, -2, 6};

    size_t i = 0;
    for (i = 0; i < sizeof(s) / sizeof(ssize_t); ++i) {
        cur = (struct node_info *)malloc(sizeof(struct node_info));
        cur->data = s[i];
        btree.add(&btree, &cur->bnode, cmp);
    }

    struct node_info key = {6};
    struct bnode_info *search_ret = NULL;


 

    printf("del node %ld\n", key.data);
    if (search_ret = btree.search(&btree, &key.bnode, cmp)) {
        btree.del(&btree, search_ret, m_free);
    }

    printf("preorder\n");
    btree.preorder(&btree, print_node);
    printf("\n");
    printf("inorder\n");
    btree.inorder(&btree, print_node);
    printf("\n");
    printf("postorder\n");
    btree.postorder(&btree, print_node);
    printf("\n");
    printf("levelorder\n");
    btree.levelorder(&btree, print_node);
    printf("\n");

    btree_destroy(&btree, m_free);

    return 0;
}


09btree/main/Makefile

SRCS := test.c
SUBDIR := 

$(BUILT_IN): $(SRCS:.c=.o) $(SUBDIR)
    $(LD) $(LDFLAGS) -r -o $@ $(SRCS:.c=.o) $(SUBDIR:=/$(BUILT_IN))

$(SUBDIR):
    $(MAKE) -C $@

$(SRCS:.c=.o):
    $(CC) $(CFLAGS) -c $<

$(DEP): $(SRCS)
    $(CC) $(CFLAGS) -MM $(SRCS) >$@
    sed -i "s/: / $@: /g" $@

sinclude $(DEP)

.PHONY: clean $(SUBDIR)

clean:
    for dir in $(SUBDIR); do \
        $(MAKE) -C $$dir clean; \
    done
    $(RM) $(SRCS:.c=.o) $(BUILT_IN) $(DEP)


09btree/queue/list.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"


static void __list_add(struct node_info *prev,
        struct node_info *next,
        const void *data_entry,
        size_t data_size)
{
    struct node_info *node = (struct node_info *)malloc(sizeof(struct node_info) + data_size);
    memcpy(node->priv, data_entry, data_size);

    node->prev = prev;
    node->next = next;
    prev->next = node;
    next->prev = node;
}


 

static void list_add(struct list_info *info,
        const void *data_entry, size_t data_size)
{
    __list_add(info->head, info->head->next,
            data_entry, data_size);
}

static void list_add_tail(struct list_info *info,
        const void *data_entry, size_t data_size)
{
    __list_add(info->head->prev, info->head,
            data_entry, data_size);
}


 

static void list_del(struct list_info *info,
        struct node_info *node,
        size_t data_size)
{
    node->prev->next = node->next;
    node->next->prev = node->prev;
    node->prev = node;
    node->next = node;

    if (data_size) {
        memset(node->priv, 0, data_size);
    }
    free(node);
}

void list_init(struct list_info *info)
{
    info->head = (struct node_info *)malloc(sizeof(struct node_info));
    info->head->prev = info->head;
    info->head->next = info->head;

    info->add = list_add;
    info->add_tail = list_add_tail;
    info->del = list_del;
}

void list_destroy(struct list_info *info)
{
    struct node_info *cur = info->head->next;

    for (; cur != info->head; cur = info->head->next) {
        list_del(info, cur, 0);
    }

    free(info->head);
}


09btree/queue/queue.c

#include <stdio.h>
#include <string.h>
#include "queue.h"


static void queue_push(struct queue_info *info,
        const void *data_entry,
        size_t data_size)
{
    info->list.add_tail(&info->list, data_entry, data_size);
}

static int queue_isempty(struct queue_info *info)
{
    return info->list.head->next == info->list.head;
}

static int queue_top(struct queue_info *info,
        void *data_entry,
        size_t data_size)
{
    if (queue_isempty(info)) {
        return -1; 
    }   

    if (data_entry) {
        memcpy(data_entry, info->list.head->next->priv, data_size);
    }   
    return 0;
}


 

static int queue_pop(struct queue_info *info,
        void *data_entry,
        size_t data_size)
{
    if (queue_top(info, data_entry, data_size) < 0) {
        return -1; 
    }

    //?..绗.?涓..?..?
    info->list.del(&info->list, info->list.head->next, data_size);
    return 0;
}

void queue_init(struct queue_info *info)
{
    list_init(&info->list);
    info->push = queue_push;
    info->pop = queue_pop;
    info->top = queue_top;
    info->isempty = queue_isempty;
}

void queue_destroy(struct queue_info *info)
{
    list_destroy(&info->list);
}


09btree/queue/Makefile

SRCS := list.c queue.c
SUBDIR := 

$(BUILT_IN): $(SRCS:.c=.o) $(SUBDIR)
    $(LD) $(LDFLAGS) -r -o $@ $(SRCS:.c=.o) $(SUBDIR:=/$(BUILT_IN))

$(SUBDIR):
    $(MAKE) -C $@

$(SRCS:.c=.o):
    $(CC) $(CFLAGS) -c $<

$(DEP): $(SRCS)
    $(CC) $(CFLAGS) -MM $(SRCS) >$@
    sed -i "s/: / $@: /g" $@

sinclude $(DEP)

.PHONY: clean $(SUBDIR)

clean:
    for dir in $(SUBDIR); do \
        $(MAKE) -C $$dir clean; \
    done
    $(RM) $(SRCS:.c=.o) $(BUILT_IN) $(DEP)



 

你可能感兴趣的:(09btree)