Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 基于堆栈的树遍历的时间复杂度_Algorithm_Tree_Stack_Time Complexity_Traversal - Fatal编程技术网

Algorithm 基于堆栈的树遍历的时间复杂度

Algorithm 基于堆栈的树遍历的时间复杂度,algorithm,tree,stack,time-complexity,traversal,Algorithm,Tree,Stack,Time Complexity,Traversal,下面实现二叉树遍历的时间复杂度是多少 void Tree::nonRecInOrder() { // nonrecursive inOrder Traversal using Stack Stack< TreeNode* > s ; // declare and initialize stack TreeNode* currentNode = root ; while( true ) { while( currentNode

下面实现二叉树遍历的时间复杂度是多少

void Tree::nonRecInOrder()
{
    // nonrecursive inOrder Traversal using Stack
    Stack< TreeNode* > s ; // declare and initialize stack
    TreeNode* currentNode = root ;

    while( true )
    {
        while( currentNode )
        {
            // move down leftChild fields
            s.add( currentNode ) ;
            currentNode = currentNode->leftChild ;
        }

         if( ! s.isEmpty() ) // stack is not empty
         {
             currentNode = *s.del( currentNode ) ; // delete from stack
             cout << currentNode->data ;
             currentNode = currentNode->rightChild ;
         }
         else
         {
            break ;
         }
    }    
}
void树::nonRecInOrder()
{
//使用堆栈的非递归顺序遍历
堆栈s;//声明并初始化堆栈
TreeNode*currentNode=root;
while(true)
{
while(当前节点)
{
//向下移动leftChild字段
s、 添加(当前节点);
currentNode=currentNode->leftChild;
}
如果(!s.isEmpty())//堆栈不是空的
{
currentNode=*s.del(currentNode);//从堆栈中删除
cout数据;
currentNode=currentNode->rightChild;
}
其他的
{
打破
}
}    
}

您还可以解释一下如何计算复杂度吗?

描述一个困难函数的大O复杂度的一种方法是考虑它访问的某些资源,然后限制该资源被访问的次数。在这种情况下,当您进行树遍历时,您可能会考虑每个节点从堆栈中推送或弹出的次数。这是一个很好的界限的原因是,该函数的所有艰苦工作(内部循环通过一个节点链向下下降,外部循环处理堆栈上的最顶端)都可以通过将节点推到堆栈上或从堆栈中弹出的次数来限定。这是因为最外层的循环在堆栈为空时终止,因此它的运行次数不能超过堆栈被推到它上面的次数,而最内层的循环的工作次数与在循环过程中被推到堆栈上面的次数成正比

让我们来看看如何把这些量绑定起来。第一个问题是每个节点可以添加到堆栈中多少次。那么,只有当循环开始执行时,一个节点或它的一个祖先(沿着仅左路径)是当前节点时,才会添加到堆栈中。这种情况会发生多少次?我的主张是,这种情况最多发生一次。证明这一点的是基于树中节点深度的归纳法。我们使用的观察结果是,如果某个节点是堆栈中某个节点的直接右子节点,则只会再次选择该节点作为当前节点。作为归纳的基本情况,如果节点是根(深度为零),则不能再次选择它,因为它没有父节点。对于归纳步骤,如果深度d处的节点不能两次被选为当前节点是真的,那么深度d+1处的节点不能被选两次,因为深度d+1处的节点只有在其父节点再次被选时才会被选,但根据归纳假设,我们知道这不是真的。因此,我们发现没有节点被两次选择为当前节点。接下来我们观察到,在循环开始时,没有一个节点是左子节点,因为当前节点要么是根节点(不是左子节点),要么是某个节点的右子节点。这种说法,再加上没有节点被访问两次这一事实,意味着一个节点最多只被添加到队列中一次,当其左上祖先成为当前节点时就会发生这种情况

这也给了我们一个可能的出列数量的界限,因为出列的数量不能超过排队的数量。因为每个节点最多排队一次,所以它也最多退队一次。最后,我们知道整个函数的复杂度是由执行的排队和退队的数量所限定的,因此复杂度是O(n),其中n是节点的数量

唷!分析这一点并不有趣。我更喜欢递归版本。:-)