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

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

二叉树结点
public calss TreeNode(){
	int data;
	TreeNode left;
	TreeNode right;
	public TreeNode(data){
	this.data = data;
}
//前序遍历
public calss XX{
	List list = new ArrayList<>();
	ppublic void dfs(TreeNode node){
		if(node == null) return;
		list.add(node.data);
		dfs(node.left);
		dfs(node.right);
	}
}
//中序遍历
public calss ZX{
	List list = new ArrayList<>();
	ppublic void dfs(TreeNode node){
		if(node == null) return;
		dfs(node.left);
		list.add(node.data);
		dfs(node.right);
	}
}
//后序遍历
public calss HX{
	List list = new ArrayList<>();
	ppublic void dfs(TreeNode node){
		if(node == null) return;
		dfs(node.left);
		dfs(node.right);
		list.add(node.data);
	}
}
package cn.kales.algorithm.test.test01;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Tree {

    //二叉树的层次遍历,需要一个队列来维持
    //开始时,将根节点放入对列,,之后从队列头开始,依次将遍历的节点删除,
    //每删除一个节点,将其左子树,右子树,一次加入队列
    //直到队列为空结束
    public void cengxu(Node root){

        if (root == null)
            System.out.println("树为空");

        List<Node> list = new ArrayList();
        list.add(root);
        List<Integer> visit = new ArrayList();

        while(!list.isEmpty()){
            Node temp = list.remove(0);
            if (temp.left != null) list.add(temp.left);
            if (temp.left != null) list.add(temp.right);
            visit.add(temp.data);   //访问结点
        }
    }

    //先序遍历,递归版

    public void xianxu_1(Node root,List<Integer> visit){
        if (root == null) return;
        visit.add(root.data);//访问结点
        xianxu_1(root.left,visit);
        xianxu_1(root.right,visit);
    }
    //先序非递归版  (迭代法)
    //需要一个栈来辅助实现,由于栈的特点因此,,先将右孩子入栈,再将左孩子入栈
    public void xianxu_2(Node root,List<Integer> visit){
        if(root == null) return;
        Stack<Node> stack = new Stack<>();
        stack.push(root);

        while(!stack.isEmpty()){
            Node temp = stack.pop();
            visit.add(temp.data);   //访问结点
            if(temp.right != null)
                stack.push(temp.right);
            if (temp.left != null)
                stack.push(temp.left);
        }
    }

    //中序遍历  递归版
    public void zhongxu_1(Node root,List<Integer> visit){
        if (root == null) return;
        zhongxu_1(root.left,visit);
        visit.add(root.data);
        zhongxu_1(root.right,visit);
    }

    //中序遍历,非递归版
    //1、从根结点,,不断将左孩子压入栈,,将所有左孩子节点压入栈
    //2、弹出栈首结点,加入遍历数组,然后将其右孩子压入栈,重复一
    //3、当栈为空时,结束
    public void zhongxu_2(Node root,List<Integer> visit){
        if (root == null) return;

        Stack<Node> stack = new Stack<>();
        Node cur = root;
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);//根节点入栈
                cur = cur.left;//循环左孩子压入栈
            }
            Node temp = stack.pop();//左孩子循环完毕后,从栈首开始弹出并访问
            visit.add(temp.data);
            cur = temp.right;
        }
    }

    //后序遍历  递归版
    public void houxu_1(Node root,List<Integer> visit){
        if (root == null) return;
        houxu_1(root.left, visit);
        houxu_1(root.left, visit);
        visit.add(root.data);
    }

    //后序遍历 非递归版
    //从根节点开始,先循环将左孩子全部压入栈,
    //判断:若栈顶(此时栈顶为最左结点),,的右子树为空或者右子树已经遍历过,则弹出栈顶元素,并遍历
    //否则,,先去访问右子树
    public void houxu_2(Node root,List<Integer> visit){
        Stack<Node> stack = new Stack<>();
        Node cur = root;
        Node pre = null;

        while (cur != null || !stack.isEmpty()){
            while(cur != null){//循环添加左孩子
                stack.push(cur);
                cur = cur.left;
            }
            Node temp = stack.peek();   //获取栈顶的最左的结点,但不弹出
            //在不存在右结点或者右节点已经访问过的情况下,访问根节点
            if (temp.right == null || temp.right == pre){
                stack.pop();
                visit.add(temp.data);
                pre = temp;
                cur = null;     //每访问一次根节点,便将cur = null;
                                // 因为该节点的子节点已经访问过,或者为空,接下来要去做的就是去考虑栈顶的元素
            }else{
                cur = temp.right;
            }
        }
    }
    //另一种后序遍历:用两个栈辅助
    //1、新建两个栈s1 , s2,,将根节点先押入s1
    //2、将s1中的栈顶元素弹出,弹出的栈顶元素压入s2中,并将其左孩子和右孩子压入栈,(从s1中出栈的顺序为:中,右,左)
    //3、重复步骤二,,直到栈s1为空
    //依次压入栈s2的顺序为中,右,左,,因此从s2中弹出时为左、右、中

    public void houxu_3(Node root,List<Integer> visit){
        if (root == null) return;

        Stack<Node> stack1 = new Stack<>();
        Stack<Node> stack2 = new Stack<>();
        stack1.push(root);

        while (!stack1.isEmpty()){
            Node temp = stack1.pop();   //弹出stack1栈顶元素
            stack2.push(temp);          //弹出的元素压入栈stack2
            if (temp.left != null) stack1.push(temp.left);
            if (temp.right != null) stack1.push(temp.right);
        }

        while(!stack2.isEmpty()){
            visit.add(stack1.pop().data);
        }
    }
}

class Node{
    int data;
    Node left;
    Node right;
    public Node (int data){
        this.data = data;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值