使用内核数据结构:红黑树 rbtree

一、使用内核红黑树文件rbtree

1.1 内核红黑树文件

        rbtree.h:/usr/src/kernels/2.6.32-279.el6.x86_64/include/linux/rbtree.h

        rbtree.c:/usr/src/kernels/2.6.32-279.el6.x86_64/lib/rbtree.c

1.2 修改rbtree.h

修改包含头文件,增加3个宏定义:

//删除以下两行代码
//#include <linux/kernel.h>
//#include <linux/stddef.h>

//增加下面3个宏定义
/* 2.6.32-279.el6.x86_64/include/linux/stddef.h  */
#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

/* 2.6.32-279.el6.x86_64/include/linux/stddef.h  */
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

/* 2.6.32-279.el6.x86_64/include/linux/kernel.h  */
#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

1.3 修改rbtree.c

修改包含头文件的代码:

//删除以下两行代码
//#include <linux/rbtree.h>
//#include <linux/module.h>

//增加包含头文件的代码
#include "rbtree.h"
删除所有的EXPORT_SYMBOL宏:

//EXPORT_SYMBOL(rb_insert_color);
//EXPORT_SYMBOL(rb_erase);
//EXPORT_SYMBOL(rb_first);
//EXPORT_SYMBOL(rb_last);
//EXPORT_SYMBOL(rb_next);
//EXPORT_SYMBOL(rb_prev);
//EXPORT_SYMBOL(rb_replace_node);

二、代码

2.1 test.c

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

struct rbt_data
{
    struct rb_node data_node;
	int num;
};

struct rbt_data* rbt_search(struct rb_root *root, int num)
{
    struct rb_node *node = root->rb_node;

    while(node)
    {
        struct rbt_data *data = container_of(node, struct rbt_data, data_node);

		if (num < data->num)
			node = node->rb_left;
		else if (num > data->num)
			node = node->rb_right;
		else
			return data;
    }
	
    return NULL;
}

int rbt_insert(struct rb_root *root, struct rbt_data *data)
{
    struct rb_node **tmp = &(root->rb_node);
	struct rb_node *parent = NULL;

	while (*tmp)
	{
	    struct rbt_data *cur = container_of(*tmp, struct rbt_data, data_node);

		parent = *tmp;
		if(data->num < cur->num)
			tmp = &((*tmp)->rb_left);
		else if(data->num > cur->num)
			tmp = &((*tmp)->rb_right);
		else
			return -1;
	}

	rb_link_node(&(data->data_node), parent, tmp);
	rb_insert_color(&(data->data_node), root);

    return 0;
}

void rbt_delete(struct rb_root *root, int num)
{
	struct rbt_data *data = rbt_search(root, num);
	if (!data)
	{
	    fprintf(stderr, "Not fount %d.\n", num);
		return;
	}

	rb_erase(&(data->data_node), root);
	free(data);
	
}

void print_rbtree(struct rb_root *root)
{
    struct rb_node *node;

	for(node = rb_first(root); node; node = rb_next(node))
		printf("%d ", rb_entry(node, struct rbt_data, data_node)->num);

	printf("\n");
}

int main(int argc, char*argv[])
{
	struct rb_root root = RB_ROOT;

	struct rbt_data *data;
	int i;

	printf("please enter 5 integers:\n");
	for(i=0; i<5; i++)
	{
	    data = malloc(sizeof(struct rbt_data));
		if(!data)
		{
			perror("fail to malloc.");
		}

		scanf("%d", &data->num);

		int ret = rbt_insert(&root, data);
		if (ret < 0)
		{
		    fprintf(stderr, "the %d already exists.\n", data->num);
			i--;
			free(data);
		}
	}

	printf("\nthe first output:\n");
	print_rbtree(&root);

    int num;
	printf("\nplease enter the num to delete:\n");
	scanf("%d", &num);
	rbt_delete(&root, num);

    printf("\nthe second output:\n");
	print_rbtree(&root);
    
	return 0;
}

三、编译执行

3.1 编译

         gcc test.c rbtree.c -o test

3.2 执行结果

使用内核数据结构:红黑树 rbtree_第1张图片



参考资料:

        红黑树(经典讲解):http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html

        详解Linux内核红黑树算法的实现:http://blog.csdn.net/npy_lp/article/details/7420689

        红黑树:http://blog.csdn.net/eric491179912/article/details/6179908

        AVL树的旋转:http://blog.csdn.net/gabriel1026/article/details/6311339

        二叉查找树中节点的删除:http://blog.csdn.net/sb1ue/article/details/8922326

        #pragma pack(n)和__attribute__((aligned(m)))的区别:http://blog.163.com/tyw_andy/blog/static/11679021200910635047652/

你可能感兴趣的:(使用内核数据结构:红黑树 rbtree)