linux内核中多处用到孩子兄弟结构来组织一些相同类型的数据。如task_struct,dentry,vfs_mount等,结构图如下:
实现原理很简单,主要有三个字段:
parent:指向父结构的指针
children:子结构链表的头
sibling:将自己连接到父节点的子结构链表中。
结构定义如下:
typedef struct _list {
struct _list *prev;
struct _list *post;
}list_t;
typedef struct _mutilist {
struct _mutilist *parent;
list_t children;
list_t sibling;
int val;
}mutilist_t;
函数声明:
void mutilist_addson (mutilist_t *node, int data);
mutilist_t* mutilist_getson (mutilist_t *node);
mutilist_t* mutilist_getparent (mutilist_t *node);
mutilist_t* mutilist_getbrother (mutilist_t *node);
宏:将嵌入节点中的连接点地址转换成节点的首地址
#define GET_PTR(_t,_m,_p) (_t*)((unsigned long)_p-((unsigned long)(&((_t*)0)->_m)))
函数实现:
#include "mutilist.h"
#include <stdio.h>
#include <malloc.h>
void mutilist_addson (mutilist_t *node, int data) {
mutilist_t *son = (mutilist_t*)malloc(sizeof(mutilist_t));
son->val = data;
son->parent = node;
son->sibling.post = node->children.post;
if (node->children.post) {
node->children.post->prev = &son->sibling;
}
node->children.post = &son->sibling;
son->sibling.prev = &node->children;
son->children.prev = 0;
son->children.post = 0;
}
mutilist_t* mutilist_getson (mutilist_t *node) {
if (!node) {
return 0;
}
return GET_PTR(mutilist_t,sibling,node->children.post);
}
mutilist_t* mutilist_getparent (mutilist_t *node) {
if (!node) {
return 0;
}
return node->parent;
}
mutilist_t* mutilist_getbrother (mutilist_t *node) {
if (!node) {
return 0;
}
return GET_PTR(mutilist_t,sibling,node->sibling.post);
}
void display (mutilist_t *node, int index) {
int i;
if (!node) {
return;
}
for (i = 0; i < index; ++i) {
printf (" ");
}
printf ("%d\n",node->val);
if (node->children.post) {
display (GET_PTR(mutilist_t,sibling,node->children.post), index+1);
}
if (node->sibling.post) {
display (GET_PTR(mutilist_t,sibling,node->sibling.post), index);
}
}
测试:
int main (void) {
mutilist_t* root = (mutilist_t*)malloc(sizeof(mutilist_t));
mutilist_t *son1, *son2, *son3, *son4;
// init root
root->val = 0;
root->sibling.post = 0;
root->sibling.prev = 0;
root->children.post = 0;
root->children.prev = 0;
root->parent = 0;
mutilist_addson (root, 1);
mutilist_addson (root, 2);
mutilist_addson (root, 3);
mutilist_addson (root, 4);
son1 = mutilist_getson (root);
mutilist_addson (son1, 5);
mutilist_addson (son1, 6);
mutilist_addson (son1, 7);
mutilist_addson (son1, 8);
son2 = mutilist_getbrother (son1);
mutilist_addson (son2, 6);
mutilist_addson (son2, 9);
mutilist_addson (son2, 1);
mutilist_addson (son2, 7);
son3 = mutilist_getbrother (son2);
mutilist_addson (son3, 6);
mutilist_addson (son3, 3);
mutilist_addson (son3, 3);
mutilist_addson (son3, 3);
son4 = mutilist_getbrother (son3);
mutilist_addson (son4, 4);
mutilist_addson (son4, 5);
mutilist_addson (son4, 7);
mutilist_addson (son4, 3);
display (root, 0);
return 0;
}
输出: