2019-11-26 |

023-从上往下打印二叉树

A
B
C
D
答案:

译文描述

从上往下打印出二叉树的每个副本,同层中断从左至右打印。

#分析

其实就是层次遍历,这个我们在我之前的文章博客里面将的很清楚了

二叉树的遍历详解(前序中序后序层次-递归和非递归)

其中调试的时候使用了

剑指优惠--006-改造二叉树来辅助我们通过前序和中序遍历的序列来生成二叉树

直接粘贴代码,只需要直接将我们层次遍历输出过程,变成将输入压入vector中即可

包括 < iostream >包括 <向量>包括 < deque >包括 <类别>

使用 名称空间 std 

//    调试开关定义 __tmain主

#IFDEF __tmain

#定义 调试指令

#其他定义 调试 0 && cout

#ENDIF  // __tmain定义 undebug  0 && cout


#IFDEF __tmain
  结构 树节点
{
	int val;
	struct  TreeNode *左;
	struct  TreeNode *正确;

	TreeNode int x)
	:val(x),左(NULL),右(NULL)
    {
	}
};
#ENDIF  // __tmain



 解决方案
{
    向量< int > res;
public:  
    vector < int > PrintFromTopToBottom(TreeNode *根)
    {
        // /方法1-=>循环调用递归打印每一层
        LevelOrder(根);

        // /方法2-=>使用两个双端
        层次LevelOrderDev(根);

        // /方法3-=>使用双指针标识当前指针和结束
        LevelOrderUsePoint(根);

        // /方法4-=>使用aprent和childzsizesize标识前一层和当前层的路由器
        个数LevelOrderUseSize(根);

        // /方法4-=>在层次中插入结束标识来标识当前层结束
        LevelOrderUseEnd(根);
        返回  ->水库;
    }

    // /打印某些层的例程,递归实现
    int  PrintLevel(TreeNode * root, int 等级)
    {
        如果(root == NULL || 等级< 0)
        {
            返回 0 ;
        }
        否则 ,如果(水平== 0)
        {
            调试<< root-> val ;
            水库push_back(root-> val);        // /在向量中添加结果

            返回 1 ;
        }
        其他
        {
            返回 PrintLevel(root-> level- 1)+ PrintLevel(root-> level- 1);
        }
    }

    // /循环每层输出其例程,调用递归归零函数
    void  LevelOrder(TreeNode * root)
    {
        水库清除();           // /将结果加到向量中
        if(root == NULL)
        {
            奖励 ;
        }
        对于 int level = 0 ;; ++级)
        {
            如果 PrintLevel(根,级别)== 0)
            {
                休息 ;
            }
            调试<< endl;
        }
    }

    // //////////////////////// 
    // /使用两个双端队列
    // ///////////// /////////// 
    void  LevelOrderDev(TreeNode *根)
    {
        水库清除();           // /在向量中添加结果

        // / deque双端高分子,
        // /支持继承器,有push_back()方法,
        // /跟vector差不多,比vector多了个pop_front,push_front方法

        deque <TreeNode *> qFirst,qSecond;
        q首先。的push_back(根);

        (qFirst。()!=)
        {
            (qFirst。()!=)
            {
                TreeNode * temp = qFirst。();
                q首先。pop_front();

                调试<< temp-> val ;
                水库push_back(temp-> val);        // /在向量中添加结果


                如果(temp-> left!= NULL)
                {
                    q第二。push_back(temp-> );
                }
                如果(temp-> right!= NULL)
                {
                    q第二。push_back(temp-> right);
                }
            }
            调试<< endl;交换(qSecond); 
            q首先。

        }
    }


    // ////////////////////// 
    ///使用双指针标识当前指针和结束
    // /////////// // /////////// 
    void  LevelOrderUsePoint(TreeNode *根)
    {
        水库清除();           // /在向量中添加结果

        向量<TreeNode *> vec;
        。VEC 的push_back(根);

        int cur = 0 ;
        int end = 1(CUR <VEC。大小())
        {
            结束= vec。大小();       // /新的一行访问开始,重新定位end于当前行最后一个例程的下一个位置

            一会儿(cur <结束)
            {
                调试<< vec [cur]-> val ;  // _ /访问股东  
                资源。push_back(vec [cur]-> val);        // /在向量中添加结果

                if(vec [cur]-> left!= NULL // /压入左例程
                {
                    。VEC 的push_back(VEC [CUR] - > );

                }
                if(vec [cur]-> right!= NULL // /压入右例程
                {
                    。VEC 的push_back(VEC [CUR] - > );
                }
                cur ++;
            }
            调试<< endl;
        }
    }


    // /////////////////////// 
    ///使用aprent和childzsizesize标识前一层和当前层的例程个数
    // //// ////////////////// 
    void  LevelOrderUseSize(TreeNode *根)
    {
        水库清除();           // /在向量中添加结果

        int parentSize = 1,childSize = 0;
        TreeNode * temp = NULL ;

        队列<TreeNode *> q;
        q。(root);
        (q。()!= true)
        {
            温度= q ();
            调试<< temp-> val ;
            水库push_back(temp-> val);        // /在向量中添加结果

            q。();

            如果(temp-> left!= NULL)
            {
                q。(temp-> left);

                childSize ++;
            }
            如果(temp-> right!= NULL)
            {
                q。(temp-> right);
                childSize ++;
            }

            parentSize--;
            如果(parentSize == 0)
            {
                parentSize = childSize;
                childSize = 0 ;
                调试<< endl;
            }

        }
    }

    // //////////////////////// 
    // /在队列中插入结束标识来标识当前层结束
    // //////// ////////////// 
    void  LevelOrderUseEnd(TreeNode *根)
    {
        水库清除();           // /在向量中添加结果

        队列<TreeNode *> q;

        q。(root);
        q。按下NULL);

        (q。()!= true)
        {
            TreeNode *基线= q。();
            :Q 弹出();

            如果(议)
            {
                调试<< node-> val ;
                水库push_back(node-> val);        // /在向量中添加结果

                如果(node-> left!= NULL)
                {
                    q。(node-> left);
                }
                如果(node-> right!= NULL)
                {
                    q。(node-> right);
                }
            }
            否则 ,如果(Q。()!=)
            {
                q。按下NULL);
                调试<< endl;
            }
        }
    }


    struct  TreeNode * reConstructBinaryTree(向量< int > pre,向量< int > in)
    {
        //    前序遍历的长度跟中序遍历的长度应该相同
        ,如果(前。大小()!= IN。大小())
        {
            取消调试<<  PRE和IN的长度应为smae  << endl;
             返回 NULL ;
        }

        //长度不能为0 
        int size = pre。大小();
        如果(大小== 0)
        {
            undebug << 这是一个NULL树(长度= 0) << endl;
             返回 NULL ;
        }

        int length = pre。大小();
        解除调试<< 树的长度=  << length << endl;
        int值= pre [ 0 ];      //    前序遍历的第一个结点是根节点  
        TreeNode * root = new  TreeNode(值);

        解除调试<< 的根是 << root-> val << endl;
        //    在中序遍历中查找到根的位置
        int rootIndex = 0 ;
         对于(rootIndex = 0 ; rootIndex <长度; rootIndex ++)
        {
            如果(在[rootIndex] ==值中)
            {取消调试<< “,在IN  << endl 中的 << rootIndex
                << 找到根休息 ;
            }
        }
        如果(rootIndex> =长度)
        {
            取消调试<< 不能在IN  << endl中找到根(值=  << value << ))返回 NULL ;
        }

        // /区分左子树和右子树
        // /中序遍历中,根左边的就是左子数,右边的就是右子树
        // / /前序遍历中,根后面是先遍历左子树,然后是右子树

        // /首先确定左右子树的长度,从中中序遍历in中确定
        int leftLength = rootIndex;
        int rightLength =长度 -1 -rootIndex;解除调试
        <<  left length =  << leftLength << ,rightLength =  << rightLength << endl;
        向量< int > preLeft(leftLength),inLeft(leftLength);
        向量< int > preRight(rightLength),inRight(rightLength);
         对于int = 0 ; 我<长度; 我++)
        {
            如果(i <rootIndex)
            {
                //    前序遍历的第一个是根目录,根后面的(leftLegnth = rootIndex)-1个例程是左子树,因此是i + 1  
                preLeft [i] = pre [i + 1 ];
                //    中序遍历前(leftLength = rootIndex)-1个例程是左子树,第rootIndex个例程是根
                inLeft [i] = in [i];
                取消调试<< preLeft [i] << inLeft [i] <<   ;

            }
            否则 如果(I> rootIndex)
            {
                //    前序遍历的第一个是根子系统,根后面的(leftLegnth = rootIndex)-1个例程是左子树,后面是右子树  
                preRight [i-rootIndex- 1 ] = pre [i];
                //    中序遍历前(leftLength = rootIndex)-1个例程是左子树,第一个rootIndex个例程是根,然后是右子树  
                inRight [i-rootIndex- 1 ] = in [i];
                取消调试<< preRight [i-rootIndex- 1 ] << inRight [i-rootIndex- 1 ] <<  ;

            }
        }
        解除调试<< endl << 左树 << endl;
         对于int i = 0 ; 我<leftLength; 我++)
        {
            取消调试<< preLeft [i] << inLeft [i] <<   ;
        }
        解除调试<< endl;
        解除调试<< 正确的树 << endl;
         对于int i = 0 ; 我<rightLength; 我++)
        {
            取消调试<< preRight [i] << inRight [i] <<   ;
        }
        解除调试<< endl;


        root-> left = reConstructBinaryTree(preLeft,inLeft);
        root-> right = reConstructBinaryTree(preRight,inRight);

        返回根
    }



};

int  __tmain()
{
    INT预[] = { 1 2 4 7 3 5 6 8 };
    INT中[] = { 4 7 2 1 5 3 8 6 };

    向量< int > preOrder(pre,pre + 8);
    向量< int >    inOrder(in,in + 8);

    解决方案
    树节点*根=解决方案。reConstructBinaryTree(预购,序);
    溶PrintFromTopToBottom(根);

    返回 0 ;
}
解释:
剑指offer

发表评论

    评价:
    验证码: 点击我更换图片
    最新评论