Java学习笔记-二叉树的遍历

分别采用迭代和栈的方式对二叉树进行遍历。



import java.util.LinkedList;

public class MyTree {
    enum Order{
        PREORDER, INORDER, POSTORDER;
    }

    private class Node{
        Integer self;
        Node left;
        Node right;
        int hashCode;
        public Node(Integer i) {
            self = i;
            hashCode = i.intValue();
        }

        public Node(String s) {
            self = new Integer(s);
            hashCode = self.intValue();
        }

        public Node(int i) {
            self = new Integer(i);
            hashCode = self.intValue();
        }

        @Override
        public int hashCode() {
            return hashCode;
        }
    }

    private Node root;
    private int size=0;

    public static void main(String[] args) {
        MyTree tree = new MyTree();
        tree.add(10);
        tree.add(5);
        tree.add(15);
        tree.add(7);
        tree.add(6);
        tree.add(1);
        tree.add(11);
        tree.add(20);
        tree.add(14);
        tree.add(16);
        tree.traversal();

    }

    public void add(int i){
        doAddtoTree(new Node(i));
    }

    public void add(String s){
        doAddtoTree(new Node(s));
    }

    public void add(Integer i){
       doAddtoTree(new Node(i));
       size++;
    }
    
    public int size() {
    	return size;
    }

    public void traversal(){
        doTraversalPreOrder();
        doTraversalMidOrder();
        doTraversalPostOrder();
    }

    private void doAddtoTree(Node node){
        boolean bFound = false;
        Node curNode = root;

        if(addToRoot(node)) return;

        while(!bFound){
            if(curNode.hashCode() > node.hashCode()){
                if (curNode.left != null){
                    curNode = curNode.left;
                }else{
                    curNode.left = node;
                    bFound = true;
                }
            }else if(curNode.hashCode() < node.hashCode()){
                if (curNode.right != null){
                    curNode = curNode.right;
                }else {
                    curNode.right = node;
                    bFound = true;
                }
            }else {
                curNode.self = node.self;
                bFound = true;
            }
        }

    }

    private boolean addToRoot(Node node){
        if (root == null){
            root = node;
            return true;
        }else
            return false;
    }

    private void doTraversalPreOrder(){
        doRecursion(root, Order.PREORDER);
        System.out.println();
        doPreInStack(root, true);
        System.out.println();
    }

    private void doTraversalMidOrder(){
        doRecursion(root, Order.INORDER);
        System.out.println();
        doPreInStack(root, false);
        System.out.println();
    }

    private void doTraversalPostOrder(){
        doRecursion(root, Order.POSTORDER);
        System.out.println();
        doPostStack(root);
        System.out.println();
    }

    /*
        迭代遍历。前序(PreOrder):先自己(print),再找左子树(有则迭代),无则再找右子树(有则迭代,无则返回)
        中序(InOrder):先找左子树(有则迭代),无则自己(print),再找右子树(有则迭代,无则返回)
        后序(PostOrder):先找左子树(有则迭代),无则再找右子树(有则迭代),无则自己(print)
     */
    private void doRecursion(Node tree, Order ord){
        if (ord == Order.PREORDER) print(tree.self);

        if (tree.left != null){
            doRecursion(tree.left, ord);
        }

        if (ord == Order.INORDER) print(tree.self);

        if (tree.right != null){
            doRecursion(tree.right, ord);
        }
        
        if (ord == Order.POSTORDER) print(tree.self);
    }

    private void doPreInStack(Node tree, boolean bPre){
        LinkedList<Node> stack = new LinkedList<>();

        while((tree != null) || (!stack.isEmpty())){
            while(tree != null){
                stack.push(tree);
                if (bPre) print(tree.self);
                tree = tree.left;
            }

            while((tree==null) && (!stack.isEmpty())){
                tree = stack.pop();
                if (!bPre)print(tree.self);
                tree = tree.right;
            }
        }
    }
    /*
     * 使用栈后序遍历:
     * 1、根压栈
     * 2、如果有左孩子,左孩子入栈,如果有右孩子,右孩子入栈,循环直到叶子(左右孩子都没有)
     * 3、叶子出栈(并访问自己),访问栈顶(这个叶子的父结点)的右孩子。
     * 3.1、如果有右孩子,重复2~3.
     * 3.2、如果没有右孩子,继续出栈。
     * 4、后序遍历到根节点时栈为空,应结束
     */
    private void doPostStack(Node tree) {
    	Node root = tree;
    	LinkedList<Node> stack = new LinkedList<>();
    	
    	while((tree!=null) || (!stack.isEmpty())) {
    		while(tree!=null) {
    			stack.push(tree);
    			if(tree.left!=null) {
    				tree = tree.left;
    			}else {
    				tree = tree.right;
    			}
    		}
    		while((!stack.isEmpty()) && tree == stack.peek().right) {
    			tree = stack.pop();
    			print(tree.self);
    		}
    		if(!stack.isEmpty()) {
    			tree = stack.peek().right;
    		}else {
    			tree = null;
    		}
    		
    	}
    }

    private void print(Integer i){
        System.out.print(i+" ");
    }
}


前序:10 5 1 7 6 15 11 14 20 16
中序:1 5 6 7 10 11 14 15 16 20
后序:1 6 7 5 14 11 16 20 15 10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值