【问题标题】:Sum of ranks in a binary tree - is there a better way二叉树中的秩和 - 有没有更好的方法
【发布时间】:2014-10-05 16:43:24
【问题描述】:

也许这个问题不属于,因为这本身不是一个编程问题,如果是这种情况,我深表歉意。

我刚考了抽象数据结构,有一个问题:

树节点的等级定义如下:如果你是树的根,你的等级是0。否则,你的等级是你父母的等级+1。

设计一种算法,计算二叉树中所有节点的秩和。你的算法的运行时间是多少?

我相信我的回答可以解决这个问题,我的伪代码是这样的:

int sum_of_tree_ranks(tree node x)
{
    if x is a leaf return rank(x)
    else, return sum_of_tree_ranks(x->left_child)+sum_of_tree_ranks(x->right_child)+rank(x)
}

函数秩在哪里

int rank(tree node x)
{
    if x->parent=null return 0
    else return 1+rank(x->parent)
}

很简单,一棵树的秩和就是左子树的和+右子树的和+根的秩。

我相信这个算法的运行时间是n^2。我相信是这种情况,因为我们没有得到二叉树是平衡的。可能是树中有n 数字,但也有n 不同的“级别”,例如,树看起来像链表而不是树。所以为了计算叶子的等级,我们可能会上升 n 步。叶子的父亲将是 n-1 步等等......所以这就是n+(n-1)+(n-2)+...+1+0=O(n^2)

我的问题是,这是正确的吗?我的算法能解决问题吗?我对运行时的分析是否正确?最重要的是,有没有更好的解决方案来解决这个问题,而不是在n^2 中运行?

【问题讨论】:

    标签: math tree big-o time-complexity abstract-data-type


    【解决方案1】:

    您的算法有效。你的分析是正确的。问题可以在O(n)时间内解决:(自己照顾树叶)

    int rank(tree node x, int r)
    {
        if x is a leaf return r
        else
            return rank(x->left_child, r + 1)+ ranks(x->right_child, r + 1) + r
    }
    rank(tree->root, 0)
    

    【讨论】:

    • 在这种情况下 r 是什么?
    • 最后一行:从根开始,r 为 0。
    【解决方案2】:

    您是对的,但是有一个 O(n) 解决方案可以让您使用更“复杂”的数据结构。 让每个节点保持其排名并在您添加/删除时更新排名,这样您就可以使用 O(1) 语句:

    return 1 + node->left.rank + node->right.rank;
    

    并对树上的每个节点执行此操作以实现 O(n)

    减少复杂性时间的经验法则是:如果您可以复杂化数据结构并添加功能以适应您的问题,您可以将复杂性时间减少到 O(n) 大多数时候。

    【讨论】:

    • 我问了老师同样的问题。节点不保持它们的等级。
    • 那么在这种情况下,您可以按照@Hamid Alaei 的建议让堆栈为您保留排名
    【解决方案3】:

    它可以在O(n)时间解决,其中n is number of Nodes在二叉树中。
    它只是根节点高度为零的所有节点的高度之和。 作为

    算法: 输入具有左右子节点的二叉树
    总和=0;
    输出总和

    PrintSumOfrank(root,sum):
    if(root==NULL) return 0;
    return PrintSumOfrank(root->lchild,sum+1)+PrintSumOfRank(root->Rchild,sum+1)+sum;
    

    编辑:
    这也可以使用遍历树的队列或级别顺序来解决。
    使用队列的算法:

    int sum=0;
    int currentHeight=0;
    Node *T;
    Node *t1;
    if(T!=NULL)
    enque(T);
    while(Q is not empty) begin
    currentHeight:currentHeight+1 ;
    for each nodes in Q do 
      t1 = deque();
     if(t1->lchild!=NULL)begin
       enque(t1->lchild);sum = sum+currentHeight; 
     end if
     if(t1->rchild!=NULL)begin
       enque(t1->rchild);sum = sum+currentHeight; 
     end if
    end for 
    end while 
    print sum ;
    

    【讨论】:

    • 有些奇怪,因为在标题处,您的函数获得了 1 个参数,但随后您再次使用 2 个参数调用它。但我理解你的想法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多