您的位置:首页 > 运维架构 > Linux

linux2.4.0内存管理mmap_avl.c的一些思考记录

2012-03-22 16:11 381 查看
学校开的数据结构讲过AVL算法,我以为我看这个avl_rebalance会比较轻松,看了几十分钟后看得一头雾水,这个算法和数据结构课写的那个算法几乎完全不一样,数据结构用的是递归算法,而这里用栈和循环代替递归(显然linux这样干更高效),我发现这点后,以为看懂了,接着看下去发现我又想错了,《数据结构c描述版》是用平衡因子取值(2,  1, 0 -1 , -2),而linux取的是左右子树最高的子树的高度加上1,叶子height = 1。通过对比高度大小情况判断左右子树是否平衡。

如果有人看mmap_avl.c看到有问题而找到这篇文章,希望我上面很小一段的解释能给你些指引,然后通过自己的思考看明白这个算法。

《数据结构c描述版》的AVL算法可以看下面,一位网友写的代码:
http://blog.csdn.net/liuzongqiang/article/details/2049935
mmap_avl.c avl_rebalance函数代码:

/*
* Rebalance a tree.
* After inserting or deleting a node of a tree we have a sequence of subtrees
* nodes[0]..nodes[k-1] such that
* nodes[0] is the root and nodes[i+1] = nodes[i]->{vm_avl_left|vm_avl_right}.
*/
static void avl_rebalance (struct vm_area_struct *** nodeplaces_ptr, int count)
{
for ( ; count > 0 ; count--) {
struct vm_area_struct ** nodeplace = *--nodeplaces_ptr;
struct vm_area_struct * node = *nodeplace;
struct vm_area_struct * nodeleft = node->vm_avl_left;
struct vm_area_struct * noderight = node->vm_avl_right;
int heightleft = heightof(nodeleft);
int heightright = heightof(noderight);
if (heightright + 1 < heightleft) {
/*                                                      */
/*                            *                         */
/*                          /   \                       */
/*                       n+2      n                     */
/*                                                      */
struct vm_area_struct * nodeleftleft = nodeleft->vm_avl_left;
struct vm_area_struct * nodeleftright = nodeleft->vm_avl_right;
int heightleftright = heightof(nodeleftright);
if (heightof(nodeleftleft) >= heightleftright) {
/*                                                        */
/*                *                    n+2|n+3            */
/*              /   \                  /    \             */
/*           n+2      n      -->      /   n+1|n+2         */
/*           / \                      |    /    \         */
/*         n+1 n|n+1                 n+1  n|n+1  n        */
/*                                                        */
node->vm_avl_left = nodeleftright; nodeleft->vm_avl_right = node;
nodeleft->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightleftright);
*nodeplace = nodeleft;
} else {
/*                                                        */
/*                *                     n+2               */
/*              /   \                 /     \             */
/*           n+2      n      -->    n+1     n+1           */
/*           / \                    / \     / \           */
/*          n  n+1                 n   L   R   n          */
/*             / \                                        */
/*            L   R                                       */
/*                                                        */
nodeleft->vm_avl_right = nodeleftright->vm_avl_left;
node->vm_avl_left = nodeleftright->vm_avl_right;
nodeleftright->vm_avl_left = nodeleft;
nodeleftright->vm_avl_right = node;
nodeleft->vm_avl_height = node->vm_avl_height = heightleftright;
nodeleftright->vm_avl_height = heightleft;
*nodeplace = nodeleftright;
}
}
else if (heightleft + 1 < heightright) {
/* similar to the above, just interchange 'left' <--> 'right' */
struct vm_area_struct * noderightright = noderight->vm_avl_right;
struct vm_area_struct * noderightleft = noderight->vm_avl_left;
int heightrightleft = heightof(noderightleft);
if (heightof(noderightright) >= heightrightleft) {
node->vm_avl_right = noderightleft; noderight->vm_avl_left = node;
noderight->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightrightleft);
*nodeplace = noderight;
} else {
noderight->vm_avl_left = noderightleft->vm_avl_right;
node->vm_avl_right = noderightleft->vm_avl_left;
noderightleft->vm_avl_right = noderight;
noderightleft->vm_avl_left = node;
noderight->vm_avl_height = node->vm_avl_height = heightrightleft;
noderightleft->vm_avl_height = heightright;
*nodeplace = noderightleft;
}
}
else {
int height = (heightleft<heightright ? heightright : heightleft) + 1;
if (height == node->vm_avl_height)
break;
node->vm_avl_height = height;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息