C 是否有更快的实现此Splay树范围和?

C 是否有更快的实现此Splay树范围和?,c,algorithm,data-structures,binary-search-tree,splay-tree,C,Algorithm,Data Structures,Binary Search Tree,Splay Tree,我已经编码了一个八字树。节点是这样表示的 struct Node{ Node *l; /// The left Node Node *r; /// The right Node int v; /// The Value }; 现在,我需要知道在一定范围内树中所有数字的总和。为此,我实现了以下名为summation的函数。 void summation(Node *R, int st, int ed) { if(!R) return; if(R

我已经编码了一个八字树。节点是这样表示的

struct Node{
    Node *l;  /// The left  Node
    Node *r;  /// The right Node
    int v;    /// The Value
};
现在,我需要知道在一定范围内树中所有数字的总和。为此,我实现了以下名为
summation的函数。

void summation(Node *R, int st, int ed)
{
    if(!R) return;
    if(R->v < st){        /// should not call left side
        summation(R->r, st, ed);
    }
    else if(R->v > ed){   /// should not call right side
        summation(R->l, st, ed);
    }
    else{                /// should call both side
        ret+=R->v;
        summation(R->l, st, ed);
        summation(R->r, st, ed);
    }
    return;
}
void求和(节点*R、int-st、int-ed)
{
如果(!R)返回;
如果(R->vR,st,ed);
}
否则如果(R->v>ed){///不应该调用右侧
求和(R->l,st,ed);
}
否则{///应该调用双方
ret+=R->v;
求和(R->l,st,ed);
求和(R->R,st,ed);
}
返回;
}
ret
是一个全局
int
变量,在调用
summation
函数之前,该变量被初始化为
0
。两个参数
st
ed
定义了范围(包括)


求和
函数的复杂度为O(n)。有谁能建议更快的实现吗?

首先,作为旁注,
求和
不返回任何内容,而是操作一个全局变量,这是非常重要的。你可能应该考虑省略这个全局变量,让递归函数只返回它所发现的(并且在返回这个总和之前,调用一个调用它的进一步递归调用返回的值)。 关于您的具体问题,您可以通过以下方式优化求和操作。这将减少求和运算的增长顺序,而不会影响其他运算的增长顺序。另一方面,这将在一定程度上降低其他操作的速度。这取决于你来决定这个权衡是否对你有利

基本思路如下:

  • 在每个节点中保留另一个字段,该字段指示树中以该节点为根的项的总和

  • 经过一些思考,您可以看到如何在更新树时有效地更新这些信息

  • 经过进一步思考,您可以看到如何使用此元数据回答范围查询


  • 这是我不久前做的splay树实现,并针对SPOJ评估系统(用C++编写)进行了测试:

    此树实现支持u所要求的(范围和在
    O(log(n))
    中)


    这里的关键思想是使用split和merge来提取覆盖范围的子树。此外,每个节点都包含一个字段
    sum
    ,该字段是其子树中所有键的总和。
    sum
    字段是延迟计算的,仅在拆分操作期间中继(沿拆分线)节点不允许计算的深度。

    <代码>空洞求和(节点*R,…)< /C>节点不是类型名称。你使用C++吗?节点是我在前面提到的结构。因为你没有线索,你必须使用C++。(在C,<代码> Stutt节点{…}中;并不意味着
    类型定义结构节点{…};
    )感谢第一段中给出的建议。我会记住这一点。:)同时,也感谢您的想法。这对我帮助很大!不客气。另一个答案是基本上实现了这一点,顺便说一句。非常感谢!这正是我想要做的!我有这个想法,但无法在代码中实现。再次感谢!