• 树的三种遍历


    二叉树的先序遍历(递归)

    遍历顺序:

             1.先访问根节点
             2.左子树递归调用先序遍历
             3.右子树递归调用先序遍历
    

    图示:

    • 分析:1.输出根节点A,2.递归左子树,输出左子树的根节点B,继续遍历左边输出C,然后右边输出F,然后输出E
      3.递归右子树,输出右子树的根节点C,访问左边,输出G,G的左边没了,右边输出H,C的左边遍历完了,右边输出I。

    代码:

    void PreOrder(BinTree BT)
    {
    	if(BT){//如果树不为空
    		cout<<BT->Data;//输出根节点(先序遍历:输出结点代码在递归之前)
    		PreOrder(BT->Left);//递归左子树
    		PreOrder(BT->Left);//递归右子树
    	}
    }
    

    结果:

          - A (BDFE) (CGHI)
    

    二叉树的中序遍历(递归)

    遍历顺序:

                        1.中序遍历其左子树(递归调用)
                        2.访问根节点
                        3.中序遍历其右子树(递归调用)
    

    图示:

    • 分析:1.先访问左子树,走到底(左边没元素了),输出当前结点D,往回走,输出B,遍历B的右子树,到底输出E,然后F。2.此时A的左子树遍历完了,输出A。
      3. 接着遍历其右子树,走左边到底,输出H,再G,此时C的左边走完了,输出C,接着遍历C的右边,输出I。
    • ps:中序遍历的结果是整棵树的投影

    代码:

    void PreOrder(BinTree BT)
    {
    	if(BT){//如果树不为空
    		PreOrder(BT->Left);//递归左子树
    		cout<<BT->Data;//输出节点(中序遍历:输出结点的代码在递归中间)
    		PreOrder(BT->Left);//递归右子树
    	}
    }
    

    结果:

          -(DBEF)A (GHCI)
    

    二叉树的后序遍历(递归)

    遍历顺序:

                        1.后序遍历其左子树(递归)
                        2.后序遍历其右子树(递归)
                        3.访问根节点
    

    图示:

    • 分析:1.遍历左子树,走到底,输出D,回到B遍历右,到E,输出E,输出F,输出B,遍历A的右,遍历C的左,输出H,输出G,遍历C的右输出I,在输出C,最后输出根节点A

    代码:

    void PreOrder(BinTree BT)
    {
    	if(BT){//如果树不为空
    		PreOrder(BT->Left);//递归左子树
    		PreOrder(BT->Left);//递归右子树
    		cout<<BT->Data;//输出节点(后序遍历:输出结点代码在递归之后)
    	}
    }
    

    结果:

          - (DEFB) (HGIC) A
    

    总结:

    • 不同主要在于输出语句的位置。

    中序遍历的堆栈实现(非递归)

    遍历实现:

         1.遇到一个结点,压入栈,并遍历左子树
         2.遍历完左子树,栈顶弹出一个元素
         3.对弹出元素再遍历其右子树
    

    实现过程:

    • 首先,把根节点A入栈,访问左子树,B入栈,访问B的左子树,D,此时到底了,弹出栈顶元素D,B的左子树遍历完成,输出B,遍历B的右子树,F入栈,E入栈,E出,

    代码:

    void InOrder(BinTree BT) 
    {
    	BinTree T;
    	Stack S = CreatStack(MaxSize);//建立并初始化栈
    	while (T || !IsEmpty(S)) {//判断栈为空否
    		while (T) {
    			Push(S, T);//进栈
    			T = T->Left;//转到左子树遍历
    		}
    		if (!IsEmpty(S)) {
    			T = Pop(S);//出栈
    			cout << T->Data;//输出
    			T = T->Right;//转到右子树遍历
    		}
    	}
    }
    
    • ps: 前序遍历则只需把输出语句放在Push()前

    • ps: 后序遍历则需要将节点俩次入栈,第二次Pop时再输出,有点复杂,未做深入研究

    层次遍历的队列实现

    • 层次遍历:一层一层的遍历

    遍历顺序:

              1.根节点入队
          2.出队队首元素
          3.把出队元素的左右孩子依次入队
    

    代码:

    
    void LeveOrder(BinTree BT)
    {
    	Queue Q;
    	BinTree T;
    	if (!BT) return;//若树为空,直接返回
    	Q = CreatQueue(MaxSize);//创建并初始化队列Q
    	AddQ(Q, BT);//加入根节点
    	while (!IsEmptyQ(Q)) {
    		T = DeleteQ(Q);//出队操作
    		cout << T->Data;
    		if (T->Left)
    			AddQ(Q, T->Left);//加入左孩子
    		if (T->Right)
    			AddQ(Q, T->Right);//加入右孩子
    	}
    }
    

    结果:

          - A BC DFGI EH
    

    两种遍历确定唯一的二叉树(必须含中序遍历)

    • 若已知先序遍历顺序为:a bcdefghij和中序遍历顺序为:cbed a hgijf

    求解思路:

            1.根据先序第一个节点,确定根节点
            2.在中序中找到a,a左边的就是左子树,右边的为右子树
            3.依次对左右子树递归可确定出最后的树
  • 相关阅读:
    2020.5.28.第十三周java上机练习
    2020.5.22第十二周java作业
    2020.5.21.第十二周java上机练习
    2020.5.15.java第十一周作业
    2020.5.14.第十一周上机练习
    leetcode02大数相加
    leetcode算法题01
    近期wxss总结
    近期Freecodecamp问题总结
    freecodecamp数字转化成罗马数字
  • 原文地址:https://www.cnblogs.com/lushuang55/p/13882053.html
Copyright © 2020-2023  润新知