使用核心資料結構:紅黑樹 rbtree
阿新 • • 發佈:2019-01-30
一、使用核心紅黑樹檔案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 執行結果
參考資料: