二叉树的递归、非递归及层序遍历的Java实现

这几天的任务需要用到树,恰好刚学习了Java,就想用Java温习一下最基本的二叉树遍历操作。因为刚学习,可能代码写的不太规范和简洁,仅作个人记录。代码如下:

/** * @author qiaoyang * @version 1.0 */
class TreeNode //定义树结构
{
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val){
        this.val=val;
        TreeNode left=null;
        TreeNode right=null;
    }
}

下面是二叉树的构建方法,分为二叉树为空和非空两种情况。二叉树为空建立根节点,非空时选择合适的位置插入。

    public void insert(int val) {//构建二叉树
        if (root == null) {
            root = new TreeNode(val);
        } else {
            _insert(root, val);
        }
    }

    private void _insert(TreeNode n, int val) {
    //根节点已经存在,寻找合适插入位置
        assert n != null;
        if (val > n.val) {//有顺序,左小右大
            if (n.right != null) {
                _insert(n.right, val);
            } else {
                n.right = new TreeNode(val);
            }
        }
        else{
            if (n.left != null) {
                _insert(n.left, val);
            } else {
                n.left = new TreeNode(val);
            }
        }
    }

然后是树的层序遍历,也就是广度优先遍历的代码:

public void BFS(TreeNode root)//广度优先遍历
    {
        ArrayDeque<TreeNode> deque=new ArrayDeque<TreeNode>();
        deque.add(root);//根节点入队
        while(!deque.isEmpty()){
            TreeNode temp=deque.remove();
            System.out.print(temp.val+"--");
            if(temp.left!=null){
                deque.add(temp.left);
            }
            if(temp.right!=null){
                deque.add(temp.right);
            }
        }
    }

接下来是二叉树的三种递归遍历的代码

    public void PreOrder(TreeNode root)//先序递归遍历
    {
        if(root!=null){
            System.out.print(root.val+"--");//访问仅作输出操作
            PreOrder(root.left);
            PreOrder(root.right);
        }
    }
    public void InOorder(TreeNode root)//中序递归遍历
    {
        if(root!=null){
            InOorder(root.left);
            System.out.print(root.val+"--");
            InOorder(root.right);
        }
    }
    public void PostOrder(TreeNode root)//后序递归遍历
    {
        if(root!=null){
            PostOrder(root.left);
            PostOrder(root.right);
            System.out.print(root.val+"--");
        }
    }

接下来是二叉树的三种非递归遍历,使用栈实现

public void PreOrder_Stack(TreeNode root)//使用栈非递归遍历
    {
        Stack<TreeNode> sta=new Stack<TreeNode>();
        while(!sta.empty()||root!=null){
            if(root==null){
                TreeNode temp=sta.pop();
                root=temp.right;
            }
            else{
                System.out.print(root.val+"--");//先访问根
                sta.push(root);//记录根,方便访问右孩子
                root=root.left; 
            }
        }
    }

    public void InOorder_Stack(TreeNode root)//中序非递归遍历
    {
        Stack<TreeNode> sta=new Stack<TreeNode>();
        while(!sta.empty()||root!=null){
            if(root==null){
                TreeNode temp=sta.pop();
                System.out.print(temp.val+"--");
                root=temp.right;
            }
            else{
                sta.push(root);
                root=root.left;//从左下搜索 
            }
        }
    }
    public void PostOrder_Stack(TreeNode root)//后序非递归遍历
    {
        Stack<TreeNode> sta=new Stack<TreeNode>();
        TreeNode p=root;
        do{
    //这里不能使用while循环,必须先让循环执行一次,让栈非空,否则会死循环
            while(p!=null){//一直往左下搜索
                sta.push(p);
                p=p.left;
            }
            TreeNode q=null;
            while(!sta.empty()){
                p=sta.pop();
                if(p.right==q){
                    System.out.print(p.val+"--");
                    q=p;//记录下此时的节点
                }
                else{
                    sta.push(p);
                    p=p.right;
                    break;
                }
            }
        }while(!sta.empty());
    }

最后写了个简单的主函数进行测试

public class Main//测试
{
    public static void main(String[] args)
    {
        Tree tree=new Tree();
        int arr[]={2,4,6,7,1,5,9,12,3,0};
        for(int i=0;i<arr.length;i++){
            tree.insert(arr[i]);
        }
        System.out.println("递归遍历:");
        tree.PreOrder(tree.root);
        System.out.println("");
        tree.InOorder(tree.root);
        System.out.println("");
        tree.PostOrder(tree.root);
        System.out.println("");
        System.out.println("非递归遍历");
        tree.PreOrder_Stack(tree.root);
        System.out.println("");
        tree.InOorder_Stack(tree.root);
        System.out.println("");
        tree.PostOrder_Stack(tree.root);
        System.out.println("");
        System.out.println("广度优先遍历:");
        tree.BFS(tree.root);
    }
}

基本实现了二叉树的创建、递归和非递归遍历以及层序遍历。

你可能感兴趣的:(java,二叉树,栈,队列)