Lighty的“自适应”树

本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/13360863

Lighty里采用了“自适应树”,而且是直接借用D. Sleator在1994年实现的代码。

其实,在关键的数据结构上借用历史证明了健壮性的代码比自己重复造轮子要实际得多——如果自己实现,谁能保证这个“新家伙”不会出问题呢?

同样的案例出现在redis里的LZF压缩,pqsort功能等等。

我们来欣赏一下最关键的一个函数——splay。

/* Splay using the key i (which may or may not be in the tree.)
 * The starting root is t, and the tree used is defined by rat
 * size fields are maintained */
splay_tree * splaytree_splay (splay_tree *t, int i) {
    splay_tree N, *l, *r, *y;
    int comp, l_size, r_size;

    if (t == NULL) return t;
    N.left = N.right = NULL;
    l = r = &N;
    l_size = r_size = 0;

    for (;;) {
        comp = compare(i, t->key);
        if (comp < 0) {
            if (t->left == NULL) break;
            if (compare(i, t->left->key) < 0) {
                y = t->left;                           /* rotate right */
                t->left = y->right;
                y->right = t;
                t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (t->left == NULL) break;
            }
            r->left = t;                               /* link right */
            r = t;
            t = t->left;
            r_size += 1+node_size(r->right);
        } else if (comp > 0) {
            if (t->right == NULL) break;
            if (compare(i, t->right->key) > 0) {
                y = t->right;                          /* rotate left */
                t->right = y->left;
                y->left = t;
    t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (t->right == NULL) break;
            }
            l->right = t;                              /* link left */
            l = t;
            t = t->right;
            l_size += 1+node_size(l->left);
        } else {
            break;
        }
    }
    l_size += node_size(t->left);  /* Now l_size and r_size are the sizes of */
    r_size += node_size(t->right); /* the left and right trees we just built.*/
    t->size = l_size + r_size + 1;

    l->right = r->left = NULL;

    /* The following two loops correct the size fields of the right path  */
    /* from the left child of the root and the right path from the left   */
    /* child of the root.                                                 */
    for (y = N.right; y != NULL; y = y->right) {
        y->size = l_size;
        l_size -= 1+node_size(y->left);
    }
    for (y = N.left; y != NULL; y = y->left) {
        y->size = r_size;
        r_size -= 1+node_size(y->right);
    }

    l->right = t->left;                                /* assemble */
    r->left = t->right;
    t->left = N.right;
    t->right = N.left;

    return t;
}

自适应树具备与生俱来的“Cache”功能,在处理冷、热分明的数据时,效果非常好。但是,如果数据本身很离散,无任何规律可言,那么,采用这种数据结构会适得其反。这个时候,更好的选择或许是“红黑树”。

 今天就这样吧。早点休息了。

周一没有出去TB,在家休息,反而显得无聊了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Matlab编写的生成圣诞的代码示例: ```matlab % 设置参数 treeHeight = 10; % 圣诞的高度 treeRadius = 5; % 圣诞的半径 numLights = 50; % 圣诞上的灯光数量 % 创建圣诞的3D表面 [X, Y, Z] = cylinder(treeRadius:-treeRadius/treeHeight:0); Z = Z * treeHeight; % 对冠应用随机扰动 noise = rand(size(X)) * 0.2; X = X + noise; Y = Y + noise; % 绘制的表面 surfl(X, Y, Z); colormap winter; % 设置颜色图 % 在的顶部绘制一颗星星 hold on; starSize = treeRadius / 2; [X_star, Y_star, Z_star] = sphere; X_star = X_star * starSize; Y_star = Y_star * starSize; Z_star = Z_star * starSize + treeHeight; surf(X_star, Y_star, Z_star, 'FaceColor', 'yellow', 'EdgeColor', 'none'); % 创建白色圆圈的散点图来表示上的灯光 lightX = rand(1, numLights) * treeRadius; lightY = rand(1, numLights) * treeRadius; lightZ = rand(1, numLights) * treeHeight; scatter3(lightX, lightY, lightZ, 'filled', 'MarkerFaceColor', 'white'); % 在上绘制其他光源 lightFuncX = @(t) treeRadius * cos(t); lightFuncY = @(t) treeRadius * sin(t); t = linspace(0, 2*pi, 100); lightX = lightFuncX(t); lightY = lightFuncY(t); lightZ = linspace(0, treeHeight, 100); plot3(lightX, lightY, lightZ, 'r', 'LineWidth', 2); % 设置绘图参数 axis equal; % 设置轴限制 box on; % 打印框 view(3); % 设置视图角度 axis off; % 关闭轴标签 title('圣诞'); % 打印标题 % 清除临时变量 clearvars -except X Y Z X_star Y_star Z_star lightX lightY lightZ; ``` 运行以上代码,将生成一个3D的圣诞,并在Matlab图形窗口中显示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值