Linux内核中的红黑树的使用

最近需要使用红黑树,在网上查找资料的时候无意中发现linux内核中有个红黑树的实现,并且其代码非常的独立,现把它摘录出来。我摘录自2.6.24的内核,分为两个文件rbtree.h和rbtree.c,rbtree.h位于内核源码的include/linux目录中,rbtree.c位于内核源码的lib目录中。

rbtree.h中删除#include 和#include 两行,添加#include

对于rb_node的声明删除掉最后的__attribute__((aligned(sizeof(long))))

最后在rbtree.h中添加如下一些宏定义:

#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

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

 

在使用rbtree的时候,每个rbtree的元素都由使用者自己定义如:
struct my_item
{
  struct rb_node node;
  struct my_data_struct data;
};
其中的struct my_data_struct是自己的数据区域
struct my_data_struct
{
  long key;
  long value;
};

下面需要实现两个函数,第一个是一个search函数,形式如下:
struct my_item* _my_rbtree_search (struct rb_root* root, long key);
其中的root参数是根节点指针;key是关键字,rbtree根据它来排序以及查找。
该函数的实现如下:
struct my_item*
_my_rbtree_search (struct rb_root* root, long key)
{
  struct rb_node *node;
  struct my_item* item;
  node = root->rb_node;

  while (node)
    {
      item = rb_entry (node, struct my_item, node);
      if (item->data.key > key)
        node = node->rb_left;
      else if (item->data.key < key)
        node = node->rb_right;
      else
        {
          return item;            /* found it */
        }
    }
  return NULL;
}

下面还需要实现一个插入的函数:
void
_my_rbtree_insert (struct rb_root* root, struct my_item* item)
{
  struct rb_node **link, *parent;
  long value;
  struct my_item* p_item;
  link = &(root->rb_node);
  value = item->data.key;
  /* Go to the bottom of the tree */
  while (*link)
    {
      parent = *link;
      p_item = rb_entry(parent, struct my_item, node);
      if (p_item->data.key > value)
        link = &((*link)->rb_left);
      else if (p_item->data.key < value)
        link = &((*link)->rb_right);
      else
        return;
    }
  /* Put the new node there */
  rb_link_node(&(item->node), parent, link);
  rb_insert_color(&(item->node), root);
}

拥有了以上两个函数我们就可以实现search、insert、remove、modify、traverse等操作,下面给出大概的伪代码吧
struct my_data_struct search (struct rb_root* root, long key)
{
  struct my_data_struct data;
  struct my_item *item;
  memset (&data, 0, sizeof(struct my_data));
  item = _my_rbtree_search (root, key);
  if (NULL != item)
  {
    memcpy (&data, item->data, sizeof(struct my_data_struct));
  }
  return data;
}

int insert (struct rb_root* root, long key, long value)
{
  struct my_item  *item = (struct my_item*) malloc (sizeof(struct my_item));
  if (NULL == item)
  {
    return -1;
  }
  item->data.key = key;
  item->data.value = value;
  _my_rbtree_insert (root, item);
  return 0;
}

int remove (struct rb_root* root, long key)
{
  struct my_item* item;
  item = _my_rbtree_search (root, key);
  if (NULL != item)
  {
    rb_erase (&(item->node), root);
  }
  return 0;
}

int modify (struct rb_root* root, long key, long new_value)
{
  struct my_item* item;
  item = _my_rbtree_search (root, key);
  if (NULL != item)
  {
    item->data.value = new_value;
  }
  return 0;
}

int traverse (struct rb_root* root)
{
  struct rb_node* node;
  struct my_item* item;
  for (node = rb_first (root); node; node = rb_next (node))
  {
    item = rb_entry (node, struct my_item, node);
    printf ("key:%d/tvalue:%d/n", item->data.key, item->data.value);
  }
  return 0;
}

你可能感兴趣的:(Linux内核中的红黑树的使用)