二叉树总结(遍历二叉树)

二叉树总结(遍历二叉树)

一、前序遍历(递归方式)

/**
 * 递归方式前序遍历
 * @param headNode     二叉树的头结点
 */
public void preErgodicBinaryTree(CreateBinaryTree.TreeNode headNode){
    if (headNode==null){
        return;
    }
    System.out.print(headNode.val+" ");
    preErgodicBinaryTree(headNode.left);
    preErgodicBinaryTree(headNode.right);
}

二、前序遍历(非递归方式)

/**
 * 前序遍历非递归方式实现(使用一个栈)
 * 头结点先入栈,如果栈不为空,弹出栈顶元素,
 * 如果弹出节点的右孩子不为空,压入该节点的
 * 右孩子,然后,如果该节点的左孩子不为空,压
 * 入该节点的左节点。
 * @param node      头结点
 */
public void preErgodicByStack(CreateBinaryTree.TreeNode node){
    Stack<CreateBinaryTree.TreeNode> stack = new Stack<>();
    stack.push(node);
    while (!stack.empty()){
        node = stack.pop();
        System.out.print(node.val+" ");
        if (node.right!=null){
            stack.push(node.right);
        }
        if (node.left!=null){
            stack.push(node.left);
        }
    }
}

三、中序遍历(递归方式)

/**
 * 递归方式实现中序遍历
 * @param headNode  头结点
 */
public void midErgodicBinaryTree(CreateBinaryTree.TreeNode headNode){
    if (headNode==null){
        return;
    }
    midErgodicBinaryTree(headNode.left);
    System.out.print(headNode.val+" ");
    midErgodicBinaryTree(headNode.right);
}

四、中序遍历(非递归方式)

/**
 * 非递归的方式(栈的方式)实现中序遍历
 *如果栈不为空,或者node节点不为空,压入node节点
 * 如果压入节点一直存在左孩子,则一直压入左节点,
 * 直到为空。如果左孩子为空的且栈不为空的时候,
 * 弹出栈顶节点,并把该节点的右孩子复制给该节点,
 * 如果右孩子不为空,循环上述步骤,直到栈为空,或者
 * 节点为空。
 * @param node      头结点
 */
public void midErgodicByStack(CreateBinaryTree.TreeNode node){
    //新建一个栈,存放二叉树的元素
    Stack<CreateBinaryTree.TreeNode> stack = new Stack<>();
    while (!stack.empty()||node!=null){
        while (node!=null){
            stack.push(node);
            node = node.left;
        }
        if (!stack.empty()){
            node = stack.pop();
            System.out.print(node.val+" ");
            node = node.right;
        }
    }
}

五、后序遍历(递归方式)

/**
 * 递归方式实现后序遍历
 * @param headNode      头结点
 */
public void postErgodicBinaryTree(CreateBinaryTree.TreeNode headNode){
    if (headNode==null){
        return;
    }
    postErgodicBinaryTree(headNode.left);
    postErgodicBinaryTree(headNode.right);
    System.out.print(headNode.val+" ");
}

六、后序遍历(非递归方式一:使用二个栈)

/**
 * 非递归方式实现后序遍历(使用两个栈)
 * 1、新建两个栈,s1和s2.
 * 2、把头结点压入到s1,循环遍历s1,如果s1不为空,弹出栈顶元素,
 * 如果栈顶元素存在左孩子,则压入s1,存在右孩子也压入s1,同时把
 * 弹出的孩子压入栈s2。
 * 3、循环遍历s2,依次弹出栈顶元素。
 * @param node      节点
 */
public void postErgodicByTwoStack(CreateBinaryTree.TreeNode node){
    Stack<CreateBinaryTree.TreeNode> s1 = new Stack<>();
    Stack<CreateBinaryTree.TreeNode> s2 = new Stack<>();
    s1.push(node);
    while (!s1.empty()){
        node = s1.pop();
        if (node.left!=null){
            s1.push(node.left);
        }
        if (node.right!=null){
            s1.push(node.right);
        }
        s2.push(node);
    }

    while (!s2.empty()){
        node = s2.pop();
        System.out.print(node.val+" ");
    }
}

七、后序遍历(非递归方式一:使用一个栈)

/**
 * 非递归方式实现后序遍历(一个栈)
 * 1、新建一个栈,同时创建两个节点元素c和h,压入栈顶元素,同时把
 * 头结点赋值给h,令c为空。
 * 2、循环遍历栈,如果栈不为空,查看栈顶元素(不是弹出)赋值给c,
 *      如果栈顶元素存在左右孩子,且h不等于栈顶元素的左右孩子,则把栈顶元素的左孩子压入栈;
 *      如果不满足上述条件,但是栈顶元素存在右孩子,且h不等于栈顶元素的右孩子,则右孩子入栈。
 *      否则,弹出栈顶元素并打印,并把c赋值给h;
 *
 * 3、直至栈为空
 * @param node      头结点
 */
public void postErgodicByOneStack(CreateBinaryTree.TreeNode node){
    Stack<CreateBinaryTree.TreeNode> stack = new Stack<>();
    CreateBinaryTree.TreeNode h = new CreateBinaryTree().new TreeNode(0);
    CreateBinaryTree.TreeNode c = new CreateBinaryTree().new TreeNode(0);
    stack.push(node);
    h = node;
    c = null;
    while (!stack.empty()){
        c = stack.peek();
        if (c.left!=null&&c.right!=null&&h!=c.left&&h!=c.right){
            stack.push(c.left);
        }else if (c.right!=null&&h!=c.right){
            stack.push(c.right);
        }else {
            node = stack.pop();
            System.out.print(node.val+" ");
            h = c;
        }
    }
}

八、按层遍历二叉树(使用队列的方式)

/**
 * 分层遍历二叉树(使用队列实现)
 * 1、新建队列,且创建两个临时节点元素last和nlast,初始值均为头结点,栈顶元素压入队列
 * 2、循环遍历队列,如果不为空,队头元素出队赋值给node,并打印
 *      如果队头元素存在左孩子,左孩子入队,左孩子赋值给nlast。
 *      如果队头元素存在右孩子,右孩子入队,右孩子赋值给nlast
 *      如果队头元素等于last,换行并打印行号,把nlast赋给last.
 * 3、直至队列为空
 * @param node  头结点
 */
public void ergodicBinaryTreeByLayer(CreateBinaryTree.TreeNode node){
    LinkedList<CreateBinaryTree.TreeNode> queue = new LinkedList<>();
    //最近节点
    CreateBinaryTree.TreeNode last = node;
    //当前行的最右节点
    CreateBinaryTree.TreeNode nlast = last;
    queue.offer(node);
    //初始行号为1
    int lineNum = 1;
    System.out.print("第"+lineNum+"行");
    while (!queue.isEmpty()){
        node = queue.poll();
        //打印元素
        System.out.print(node.val+" ");
        if (node.left!=null){
            queue.offer(node.left);
            nlast = node.left;
        }
        if (node.right!=null){
            queue.offer(node.right);
            nlast = node.right;
        }
        if (node == last){
            //防止多打印行号
            if (!queue.isEmpty()){
                //打印行号
                System.out.print("\n第"+(++lineNum)+"行");
            }
            last = nlast;
        }
    }
}
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值