1

我有一个简单的递归函数,它比较两个默克尔树并累积叶节点中的差异。但是,我无法衡量它的时间复杂度。具体来说,我想看看它与比较两个哈希表或两个 BST 相比如何。在这种情况下,一组叶子是一行,它们共享一个 rowid。一组行构成了整个 merkle 树。在下面的代码中,我只是在叶级别累积差异。

def diff_helper(node1: MNode, node2: MNode, diff: List[Difference]):
    if not node1 and not node2:
        return
    elif node1.rowid==node2.rowid and node1.signature==node2.signature and node1.nodetype==NodeType.Row and node2.nodetype==NodeType.Row:
        return
    elif node1.rowid==node2.rowid and node1.signature!=node2.signature and node1.nodetype==NodeType.Row and node2.nodetype==NodeType.Row:
        diff_helper(node1.left, node2.left, diff)
        diff_helper(node1.right, node2.right, diff)
    elif node1.rowid==node2.rowid and node1.signature!=node2.signature and node1.nodetype==NodeType.Leaf and node2.nodetype==NodeType.Leaf:
        diff.append(Difference(node1.rowid, node1.column, node1.value, node2.value))
    else:
        diff_helper(node1.left, node2.left, diff)
        diff_helper(node1.right, node2.right, diff)

时间复杂度:

在最好的情况下,我看到这是一个常量操作,因为两棵树的根哈希是相同的。在最坏的情况下,比较次数是所有叶节点的总数。

问题:

我可以感觉到 merkle 树比普通哈希表做得更好,因为它能够更快地修剪树。但是,我无法用大 O 术语来表示这一点。

一个类似的哈希表实现将是对第二个哈希表进行 rowid 遍历和恒定时间查找。一旦找到 rowid 的值,如果叶级数据存储为哈希表,您可能会对每个叶进行线性比较。

4

1 回答 1

1

这是输出敏感算法的一个很好的例子,其最坏情况下的运行时间通过引入一个新量来最准确地指定。对于这个问题,如果 h 是树的高度,d 是叶子差异的数量,那么最坏的情况是 O(d + d (h - log d))。在树的第 ℓ 层,我们最多可以有 min(2 ℓ</sup>, d) 个具有差异的节点,我们可以将匹配节点的成本计入它们的父节点,因此我们只需限制这个总和。交叉点是 ℓ = log d,所以 ∑<sub>ℓ=0...log d 2 ℓ</sup> 是 2 log d + 1 − 1 = Θ(d)。然后有 h - log d 级别剩余 d 差异。

于 2021-08-07T12:24:16.747 回答