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

学校开的数据结构讲过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;
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值