关闭

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

标签: linuxstruct数据结构算法n2
558人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:70295次
    • 积分:1235
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:5篇
    • 译文:0篇
    • 评论:10条
    文章分类
    最新评论