树的建立 和 后序遍历

这篇博客介绍了如何使用递归和非递归方式来实现二叉树的后序遍历。首先,通过递归方法创建了一棵树,并提供了递归和非递归两种后序遍历的代码实现。递归方法遵循左-右-根的顺序,而非递归方法利用栈来模拟递归过程,避免了深度优先搜索的栈溢出问题。
摘要由CSDN通过智能技术生成

通过递归方式建立一棵树,之后分别给出树后序遍历的递归非递归方式

这是一棵树

终端输入:
A
B 
#
C
D
#
# 
E 
#
#
F
# 
G 
H 
# 
# 
#
//code
public class CreateTree {
    public static void main(String[] args) {
        TreeNode t = null;
        TreeNode input = input(t);
        beforeTraversal(input);
        System.out.println();
        beforeTraversal1(input);
        //System.out.println(input);
    }

    //递归方式建树
    public static TreeNode input(TreeNode T){
        Scanner scanner = new Scanner(System.in);
        String in = scanner.next();

        if("#".equals(in)){
            T = null;
        }else{
            T = new TreeNode();
            T.data = in;
            T.left = input(T.left);
            T.right = input(T.right);
        }
        return T;
    }


    //后续遍历 递归方法
    public static void beforeTraversal(TreeNode node){
        if(node!=null){
            beforeTraversal(node.left);
            beforeTraversal(node.right);
            System.out.print(node.data);
            System.out.print(" ");
        }
    }

    //后序遍历 非递归方法
    public static void beforeTraversal1(TreeNode node){
        //定义栈用于存放节点
        Stack<TreeNode> stack = new Stack<>();
        if(node!=null){
            TreeNode node1 = node;
            TreeNode cur = null;  //栈顶元素
            TreeNode h = node;    //记录最近弹出的节点
            while (true) {
                //压入树节点,直至左节点为空
                while (node1 != null) {
                    stack.push(node1);
                    node1 = node1.left;
                }

                if (!stack.isEmpty()) {
                    //节点一旦弹出就找不到了,因此在这不弹出,先进行判断
                    cur = stack.peek();
                    //当该节的右子节点为null 或者 该节点的右子节点已经打印过了
                    //根据后续排序:左 右 中,因此就应当弹出该节点
                    if (cur.right == null || cur.right == h) {
                        System.out.print(stack.pop().data);
                        System.out.print(" ");
                        //记得保留刚刚弹出的节点
                        h = cur;
                    } else {
                        //如果节点不满足上述条件,这说明还需继续压入
                        node1 = cur.right;
                    }

                }else {
                    return;
                }
            }
        }
    }
}

利用中序遍历后序遍历重建二叉的过程通常涉及到两个步骤。首先理解这两种遍历顺序: 1. **中序遍历**: - 对于任何给定节点,我们先访问它的左子(递归地) - 然后访问根节点自身 - 最后访问右子 2. **后序遍历**: - 先访问左子(如果存在) - 再访问右子(如果存在) - 最后访问根节点 要从这两个序列构建一棵,可以按照以下方法操作: - 从后序遍历中取出最后一个元素作为当前的根节点。 - 使用中序遍历找到这个根节点的位置。由于中序遍历会先遍历左子,所以我们可以在中序遍历序列中从根节点位置前移一位,直到遇到第一个大于当前根节点值的元素,这个元素就是根节点的右子节点。 - 分别对左右子节点进行同样的过程,递归地构建左子和右子。 这里有一个伪代码示例: ```python def build_tree(inorder, postorder): if inorder and postorder: root_val = postorder.pop() # 取出后序遍历中的最后一个元素,即根节点 root = TreeNode(root_val) # 创建新节点 # 找到根节点在中序遍历中的索引 in_index = inorder.index(root_val) # 使用中序遍历创建左子和右子 root.left = build_tree(inorder[:in_index], postorder[:in_index]) # 左子 root.right = build_tree(inorder[in_index+1:], postorder[in_index:]) # 右子 return root ``` 在这个过程中,`inorder`和`postorder`分别是中序遍历后序遍历的结果列表。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值