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)