• 算法导论 12.1-3


    题目:设计一个执行中序遍历的非递归算法

    解答:

    分析:

    1、使用栈模拟递归调用的过程,即可以实现中序遍历

    2、在结点中增加指针域,使该指针域指向父节点,通过迭代即可实现中序遍历

    非递归算法:

    栈模拟算法版本一:

    // InOrder Traverasl
    void InOrder( SearchTree T ) 
    {
        Stack S;
    
        while( T != NULL || !S.Empty() )
        {
            if ( T != NULL )
            {
                S.push( T );
                T = T->Left; 
            }
            else
            {
                T = S.pop();
                Visit( T );
                T = T->Right;
            }
        }
    }

    注:该算法使用深度优先搜索技巧来实现,回溯时Visit。

    栈模拟算法版本二:

    // InOrder Traverasl version2.0
    void InOrder( SearchTree T )
    {
        Stack S;
    
        
        if( T != NULL )
            S.Push( T );
        
        T->ChildPushed = false;
        while ( !S.Empty() )
        {
            SearchTree TNode = S.Pop(); 
            if ( TNode->ChildPushed )
            {   
                // 如果标识位为true,则表示其左右子树都已经入栈,那么现在就需要访问该节点了
                Visit( TNode );        
            }
            else
            {   
                // 左右子树尚未入栈,则依次将 右节点,根节点,左节点 入栈
                if ( TNode->Right != NULL )
                {
                    // 左右子树均设置为false
                    TNode->Right->ChildPushed = false; 
                    S.Push( TNode->Right );
                }
                TNode->ChildPushed = true;  // 根节点标志位为true
                S.Push( TNode );
                if ( TNode->Left != NULL )
                {
                    TNode->Left->ChildPushed = false;
                    S.Push( TNode->Left );
                }
            }
        }
    }

    注:该算法也使用深度优先搜索技巧,在回溯时在通过标志ChildPushed标记是否可以Visit。

    父节点实现版本:

    void InOrder( SearchTree T )
    {
        while ( T != NULL )
        {
            while ( T->Left != NULL && !T->Left->Visited )
                T = T->Left;
    
            if ( !T->Visited )
            {
                Visit( T );
                T->Visited = true;
            }
    
            if ( T->Right != NULL && !T->Right->Visited )
                T = T->Right;
            else
                T = T->Parent;
        }
    }

    注:使用该方法需要增加一个指向父节点的指针域,在建树时会存在一定困难

    算法时间复杂度分析:O(N)

  • 相关阅读:
    HDU 3681 Prison Break 越狱(状压DP,变形)
    POJ 2411 Mondriaan's Dream (状压DP,骨牌覆盖,经典)
    ZOJ 3471 Most Powerful (状压DP,经典)
    POJ 2288 Islands and Bridges (状压DP,变形)
    HDU 3001 Travelling (状压DP,3进制)
    POJ 3311 Hie with the Pie (状压DP)
    POJ 1185 炮兵阵地 (状压DP,轮廓线DP)
    FZU 2204 7
    POJ 3254 Corn Fields (状压DP,轮廓线DP)
    ZOJ 3494 BCD Code (数位DP,AC自动机)
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4033310.html
Copyright © 2020-2023  润新知