数据结构 --- 二叉树的三种遍历方式的Java实现

以下面的二叉树为例:

 

二叉树结点的定义:

package model;

public class TreeNode {

    private String value;
    private TreeNode lchild;
    private TreeNode rchild;

    public TreeNode(){}

    public TreeNode(String value, TreeNode lchild, TreeNode rchild) {
        this.value = value;
        this.lchild = lchild;
        this.rchild = rchild;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public TreeNode getLchild() {
        return lchild;
    }

    public void setLchild(TreeNode lchild) {
        this.lchild = lchild;
    }

    public TreeNode getRchild() {
        return rchild;
    }

    public void setRchild(TreeNode rchild) {
        this.rchild = rchild;
    }
}

二叉树的创建:

        TreeNode x = new TreeNode("x",null,null);
        TreeNode y = new TreeNode("y",null,null);
        TreeNode d = new TreeNode("d",x,y);
        TreeNode e = new TreeNode("e",null,null);
        TreeNode f = new TreeNode("f",null,null);
        TreeNode c = new TreeNode("c",e,f);
        TreeNode b = new TreeNode("b",d,null);
        TreeNode a = new TreeNode("a",b,c);

二叉树的遍历算法:

package service;

import model.TreeNode;

public interface TreeSerivce {

    /** 先序遍历(递归)*/
    void preOrder(TreeNode treeNode);

    /** 中序遍历(递归)*/
    void inOrder(TreeNode treeNode);

    /** 后序遍历(递归)*/
    void postOrder(TreeNode treeNode);

    /** 先序遍历(非递归1)*/
    void preOrderNo(TreeNode treeNode);

    /** 先序遍历(非递归2)*/
    void preOrderNo1(TreeNode treeNode);

    /** 中序遍历(非递归)*/
    void inOrderNo(TreeNode treeNode);

    /** 后序遍历(非递归1)*/
    void postOrderNo(TreeNode treeNode);

    /** 后序遍历(非递归2)*/
    void postOrderNo1(TreeNode treeNode);

    /** 层次遍历 */
    void levelOrder(TreeNode treeNode);

    /** 层次遍历 (按行打印)*/
    void levelOrder1(TreeNode treeNode);

    /**
     * 返回当前数的深度
     *  说明:
     *  1、如果一棵树只有一个结点,它的深度为1。
     *  2、如果根结点只有左子树而没有右子树,那么树的深度是其左子树的深度加1;
     *  3、如果根结点只有右子树而没有左子树,那么树的深度应该是其右子树的深度加1;
     *  4、如果既有右子树又有左子树,那该树的深度就是其左、右子树深度的较大值再加1。
     */
    int getTreeDepth(TreeNode treeNode);

    /** 序列化树 (树-> 文件)(层次遍历)*/
    void serializeTree(TreeNode treeNode);

    /** 反序列化树 (文件-> 树)(层次遍历)*/
    void reversreSerializeTree(String levelStr);

    /** 序列化树 (树-> 文件)(先序遍历:非递归)*/
    void serializeTreeByPre(TreeNode treeNode);

    /** 序列化树 (树-> 文件)(先序遍历:递归)*/
    String serializeTreeByPre1(TreeNode treeNode);

    /** 反序列化树 (文件-> 树)(先序遍历)*/
    void reverseSerializeTreeByPre(String preStr);
}
package serviceimpl;

import model.TreeNode;
import service.TreeSerivce;

import java.util.*;

public class TreeServiceImpl implements TreeSerivce {

    public void preOrder(TreeNode treeNode) {
        System.out.println(treeNode.getValue());
        if (treeNode.getLchild() != null) {
            preOrder(treeNode.getLchild());
        }
        if (treeNode.getRchild() != null) {
            preOrder(treeNode.getRchild());
        }
    }

    public void inOrder(TreeNode treeNode) {
        if (treeNode.getLchild() != null) {
            inOrder(treeNode.getLchild());
        }
        System.out.println(treeNode.getValue());
        if (treeNode.getRchild() != null) {
            inOrder(treeNode.getRchild());
        }
    }

    public void postOrder(TreeNode treeNode) {
        if (treeNode.getLchild() != null) {
            postOrder(treeNode.getLchild());
        }
        if (treeNode.getRchild() != null) {
            postOrder(treeNode.getRchild());
        }
        System.out.println(treeNode.getValue());
    }

    public void preOrderNo(TreeNode treeNode){
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while(treeNode != null || !stack.isEmpty()) {
            while(treeNode != null) {
                System.out.println(treeNode.getValue());
                stack.push(treeNode);
                treeNode = treeNode.getLchild();
            }
            if(!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.getRchild();
            }
        }
    }

    public void preOrderNo1(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode currentTreeNode;
        if (treeNode != null) {
            stack.push(treeNode);
            while (!stack.isEmpty()) {
                currentTreeNode = stack.pop();
                System.out.println(currentTreeNode.getValue());
                if (currentTreeNode.getRchild() != null) {
                    stack.push(currentTreeNode.getRchild());
                }
                if (currentTreeNode.getLchild() != null) {
                    stack.push(currentTreeNode.getLchild());
                }
            }
        }
    }

    public void inOrderNo(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while(treeNode != null || !stack.isEmpty()) {
            while(treeNode != null) {
                stack.push(treeNode);
                treeNode = treeNode.getLchild();
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                System.out.println(treeNode.getValue());
                treeNode = treeNode.getRchild();
            }
        }
    }

    public void postOrderNo(TreeNode treeNode) {
        int left = 1; // 操作的是左子树
        int right = 2; // 操作的是右子树
        Stack<TreeNode> stack = new Stack<TreeNode>();
        Stack<Integer> flagStack = new Stack<Integer>(); // 辅助栈,用于判断当前操作的是左结点还是右结点,判断根结点是否出栈
        while(treeNode != null || !stack.isEmpty()) {
            while(treeNode != null) {
                stack.push(treeNode);
                flagStack.push(left);
                treeNode = treeNode.getLchild();
            }
            while(!stack.isEmpty() && flagStack.peek() == right) {
                flagStack.pop();
                System.out.println(stack.pop().getValue());
            }
            if (!stack.isEmpty() && flagStack.peek() == left) {
                flagStack.pop();
                flagStack.push(right);
                treeNode = stack.peek().getRchild();
            }
        }
    }

    public void postOrderNo1(TreeNode treeNode) {
        Stack<TreeNode> stack1 = new Stack<TreeNode>();
        Stack<TreeNode> stack2 = new Stack<TreeNode>();
        if (treeNode != null) {
            stack1.push(treeNode);
            while(!stack1.isEmpty()) {
                treeNode = stack1.pop();
                stack2.push(treeNode);
                if (treeNode.getLchild() != null) stack1.push(treeNode.getLchild());
                if (treeNode.getRchild() != null) stack1.push(treeNode.getRchild());
            }
        }
        while(!stack2.isEmpty()) {
            System.out.print(stack2.pop().getValue() + ",");
        }
    }

    public void levelOrder(TreeNode treeNode) {
        LinkedList<TreeNode> list = new LinkedList<TreeNode>();
        list.add(treeNode);
        TreeNode currentTreeNode;
        while (!list.isEmpty()){
            currentTreeNode = list.poll();
            System.out.println(currentTreeNode.getValue());
            if (currentTreeNode.getLchild() != null) {
                list.add(currentTreeNode.getLchild());
            }
            if (currentTreeNode.getRchild() != null) {
                list.add(currentTreeNode.getRchild());
            }
        }
    }

    public void levelOrder1(TreeNode treeNode) {
        Queue<TreeNode> list = new LinkedList<TreeNode>();
        TreeNode last;
        TreeNode nlast;
        TreeNode currentTreeNode;
        if (treeNode != null) {
            list.offer(treeNode);
            last = treeNode;
            nlast = treeNode;
            while(!list.isEmpty()) {
                currentTreeNode = list.poll();
                if (currentTreeNode.getValue().equals(last.getValue())) {
                    System.out.print(currentTreeNode.getValue());
                    System.out.println();
                } else {
                    System.out.print(currentTreeNode.getValue() + ",");
                }
                if (currentTreeNode.getLchild() != null) {
                    list.offer(currentTreeNode.getLchild());
                    nlast = currentTreeNode.getLchild();
                }
                if (currentTreeNode.getRchild() != null) {
                    list.offer(currentTreeNode.getRchild());
                    nlast = currentTreeNode.getRchild();
                }
                if (currentTreeNode.getValue().equals(last.getValue())) {
                    last = nlast;
                }
            }
        }
    }

    public int getTreeDepth(TreeNode treeNode) {
        if(treeNode.getLchild() == null && treeNode.getRchild() == null)  return 1;
        int left = 0,right = 0;
        if(treeNode.getLchild() != null)  left = getTreeDepth(treeNode.getLchild());
        if(treeNode.getRchild() != null) right = getTreeDepth(treeNode.getRchild());
        return left > right ? left+1 : right+1;
    }

    public void serializeTree(TreeNode treeNode) {
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        if (treeNode != null) {
            queue.offer(treeNode);
            TreeNode currentTreeNode;
            StringBuffer sb = new StringBuffer();
            sb.append(treeNode.getValue()).append("!");
            while(!queue.isEmpty()) {
                currentTreeNode = queue.poll();
                if (currentTreeNode.getLchild() != null) {
                    queue.offer(currentTreeNode.getLchild());
                    sb.append(currentTreeNode.getLchild().getValue()).append("!");
                } else {
                    sb.append("#!");
                }
                if (currentTreeNode.getRchild() != null) {
                    queue.offer(currentTreeNode.getRchild());
                    sb.append(currentTreeNode.getRchild().getValue()).append("!");
                } else {
                    sb.append("#!");
                }
            }
            System.out.println(sb.toString());
        }
    }

    public void reversreSerializeTree(String levelStr) {
        String[] strs = levelStr.split("!");
        TreeNode treeNode = null;
        TreeNode currentTreeNode;
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        int index = 0;
        if (!strs[0].equals("#")) {
            treeNode = new TreeNode(strs[0]);
            queue.offer(treeNode);
            index++;
        }
        while (!queue.isEmpty()) {
            currentTreeNode = queue.poll();
            currentTreeNode.setLchild(strs[index].equals("#") ? null : new TreeNode(strs[index]));
            index++;
            currentTreeNode.setRchild(strs[index].equals("#") ? null : new TreeNode(strs[index]));
            index++;
            if (currentTreeNode.getLchild() != null) {
                queue.offer(currentTreeNode.getLchild());
            }
            if (currentTreeNode.getRchild() != null) {
                queue.offer(currentTreeNode.getRchild());
            }
        }
        levelOrder(treeNode);
    }

    public void serializeTreeByPre(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        StringBuffer sb = new StringBuffer();
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                sb.append(treeNode.getValue() + "!");
                stack.push(treeNode);
                treeNode = treeNode.getLchild();
                if (treeNode == null) {
                    sb.append("#!");
                }
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.getRchild();
                if (treeNode == null) {
                    sb.append("#!");
                }
            }
        }
        System.out.println(sb.toString());
    }

    public String serializeTreeByPre1(TreeNode treeNode) {
        if (treeNode == null) {
            return "#!";
        }
        String res = treeNode.getValue() + "!";
        res += serializeTreeByPre1(treeNode.getLchild());
        res += serializeTreeByPre1(treeNode.getRchild());
        return res;
    }

    public void reverseSerializeTreeByPre(String preStr) {
        String[] strs = preStr.split("!");
        Queue<String> queue = new LinkedList<String>();
        for (int i = 0; i < strs.length; i++) {
            queue.offer(strs[i]);
        }
       preOrder(reconPreOrder(queue));
    }

    private TreeNode reconPreOrder(Queue<String> queue) {
        String value = queue.poll();
        if (value.equals("#")) return null;
        TreeNode head = new TreeNode(value);
        head.setLchild(reconPreOrder(queue));
        head.setRchild(reconPreOrder(queue));
        return head;
    }
}

延伸:二叉树层次遍历的时候按行打印

思路:

1.定义两个节点last和nlast;
2.last代表当前行最右边的节点,nlast代表下一行最右边的节点(nlast一直跟踪记录队列中最新加入的结点,最新加入的结点一定是发现的下一行的最右结点。所以当前行打完时,nlast一定是下一行的最右结点。);
3.如果输出结点是last结点,说明该换行了,last=nlast。

public void levelOrder(TreeNode treeNode) {
        Queue<TreeNode> list = new LinkedList<TreeNode>();
        TreeNode last;
        TreeNode nlast;
        TreeNode currentTreeNode;
        if (treeNode != null) {
            list.offer(treeNode);
            last = treeNode;
            nlast = treeNode;
            while(!list.isEmpty()) {
                currentTreeNode = list.poll();
                if (currentTreeNode.getValue().equals(last.getValue())) {
                    System.out.print(currentTreeNode.getValue());
                    System.out.println();
                } else {
                    System.out.print(currentTreeNode.getValue() + ",");
                }
                if (currentTreeNode.getLchild() != null) {
                    list.offer(currentTreeNode.getLchild());
                    nlast = currentTreeNode.getLchild();
                }
                if (currentTreeNode.getRchild() != null) {
                    list.offer(currentTreeNode.getRchild());
                    nlast = currentTreeNode.getRchild();
                }
                if (currentTreeNode.getValue().equals(last.getValue())) {
                    last = nlast;
                }
            }
        }
    }

运行结果如下:
a
b,c
d,e,f
x,y

延伸:输入一棵二叉树,判断该二叉树是否是平衡二叉树。

Java源码实现:

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
       if (root == null) return true;
       if (root.left == null && root.right == null) return true; 
       int left = 0;
       int right = 0;
       if (root.left != null) left = TreeDepth(root.left);
       if (root.right != null) right = TreeDepth(root.right);
       if (left - right == -1 || left - right == 0 || left - right == 1) return true;
       return false;
    }
    
     private int TreeDepth(TreeNode root) {
       if (root == null) return 0;
       if (root.left == null && root.right == null) return 1; 
       int left = 0;
       int right = 0;
       if (root.left != null) left = TreeDepth(root.left);
       if (root.right != null) right = TreeDepth(root.right);
       return left >= right ? left + 1 :right+1;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值