码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树

时间:2019-10-21 13:24:12      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:结构   adc   highlight   a*   data   先序   中间   vat   markdown   

二叉树遍历,表达式树

技术图片

class TreeNode{
        private String data;
        private TreeNode left = null;
        private TreeNode right = null;

        public TreeNode(String data) {
            this.data = data;
        }
    }

表达式树

技术图片

树中的树叶是数,其他的节点是操作符,遍历有三种方式,先序,中序,后序。

遍历的结果分别是前缀中缀后缀表达式

先序

先中间的节点,后左右两个儿子

++a*bc*+*defg

递归实现

public void preOrder(TreeNode treeNode){
        if(treeNode!=null){
            System.out.print(treeNode.data);
            preOrder(treeNode.left);
            preOrder(treeNode.right);
        }
    }

非递归

public void noRecPreOrder(TreeNode p) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode node = p;
        while (node != null || stack.size() > 0) {
            while (node != null) {
                System.out.print(node.data);
                stack.push(node);
                node = node.left;
            }
            while (stack.size() > 0) {
                node = stack.pop();
                node = node.right;
                while (node != null) {
                    System.out.print(node.data);
                    stack.push(node);
                    node = node.left;
                }
            }
        }
    }

中序

先左儿子,中间节点,然后右儿子

(a +(b * c))+(((d * e) + f ) * g)

递归

 public void inOrder(TreeNode treeNode){
        if(treeNode!=null){
            inOrder(treeNode.left);
            System.out.print(treeNode.data);
            inOrder(treeNode.right);
        }
    }

非递归

  public void noRecInOrder(TreeNode p){
        Stack<TreeNode> stack =new Stack<TreeNode>();
        TreeNode node =p;
        while(node!=null||stack.size()>0){
            //存在左子树
            while(node!=null){
                stack.push(node);
                node=node.left;
            }
            //栈非空
            if(stack.size()>0){
                node=stack.pop();
                System.out.print(node.data);
                node=node.right;
            }
        }
    }

后序

先左右儿子,然后中间节点

a b c * + d e * f + g * +

递归

 public void postOrder(TreeNode treeNode) {
        if (treeNode != null) {
            postOrder(treeNode.left);
            postOrder(treeNode.right);
            System.out.print(treeNode.data);
        }
    }

非递归

 public void noRecPostOrder(TreeNode p){
        Stack<TreeNode> stack=new Stack<TreeNode>();
        TreeNode node =p;
        while(p!=null){
            //左子树入栈
            for(;p.left!=null;p=p.left){
                stack.push(p);
            }
            //当前结点无右子树或右子树已经输出
            while(p!=null&&(p.right==null||p.right==node)){
                System.out.print(p.data);
                //纪录上一个已输出结点
                node =p;
                if(stack.empty())
                    return;
                p=stack.pop();
            }
            //处理右子树
            stack.push(p);
            p=p.right;
        }
    }

构建表达式树

给定后缀表达式,利用栈读入二叉树。

假设后缀表达式为

6 5 2 3 + 8 * + 3 + *

6523节点依次入站,遇到操作符+,弾出两个节点,用+为父节点,然后压入站,8入站,*,再弾两个节点….

实现:

Stack<TreeNode> stack = new Stack<TreeNode>();
        String s = "6 5 2 3 + 8 * + 3 + *";
        String[] strings = s.split(" ");
        for (int i = 0; i < strings.length; i++) {
            if (Character.isDigit(strings[i].charAt(0))) {
                stack.push(new TreeNode(strings[i]));
            } else {
                TreeNode root = new TreeNode(strings[i]);
                root.right = stack.pop();
                root.left = stack.pop();
                stack.push(root);
            }
        }

具体实现

package com.yb.shujujiegou.shu;

import java.util.Stack;

/**
 * 表达式树的三种遍历
 * Created by 杨波 on 2017/5/7.
 */
public class BinaryTree {
    private static class TreeNode{
        private String data;
        private TreeNode left = null;
        private TreeNode right = null;

        public TreeNode(String 大专栏  二叉树"n">data) {
            this.data = data;
        }
    }
    private TreeNode root = null;
    //前序遍历
    public void preOrder(TreeNode treeNode){
        if(treeNode!=null){
            System.out.print(treeNode.data);
            preOrder(treeNode.left);
            preOrder(treeNode.right);
        }
    }
    //前序遍历的非递归实现
    public void noRecPreOrder(TreeNode p) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode node = p;
        while (node != null || stack.size() > 0) {
            while (node != null) {
                System.out.print(node.data);
                stack.push(node);
                node = node.left;
            }
            while (stack.size() > 0) {
                node = stack.pop();
                node = node.right;
                while (node != null) {
                    System.out.print(node.data);
                    stack.push(node);
                    node = node.left;
                }
            }
        }
    }

    //中序遍历
    public void inOrder(TreeNode treeNode){
        if(treeNode!=null){
            inOrder(treeNode.left);
            System.out.print(treeNode.data);
            inOrder(treeNode.right);
        }
    }
    //中序遍历的非递归实现
    public void noRecInOrder(TreeNode p){
        Stack<TreeNode> stack =new Stack<TreeNode>();
        TreeNode node =p;
        while(node!=null||stack.size()>0){
            //存在左子树
            while(node!=null){
                stack.push(node);
                node=node.left;
            }
            //栈非空
            if(stack.size()>0){
                node=stack.pop();
                System.out.print(node.data);
                node=node.right;
            }
        }
    }
    //后续遍历
    public void postOrder(TreeNode treeNode) {
        if (treeNode != null) {
            postOrder(treeNode.left);
            postOrder(treeNode.right);
            System.out.print(treeNode.data);
        }
    }
    //后序遍历的非递归实现
    public void noRecPostOrder(TreeNode p){
        Stack<TreeNode> stack=new Stack<TreeNode>();
        TreeNode node =p;
        while(p!=null){
            //左子树入栈
            for(;p.left!=null;p=p.left){
                stack.push(p);
            }
            //当前结点无右子树或右子树已经输出
            while(p!=null&&(p.right==null||p.right==node)){
                System.out.print(p.data);
                //纪录上一个已输出结点
                node =p;
                if(stack.empty())
                    return;
                p=stack.pop();
            }
            //处理右子树
            stack.push(p);
            p=p.right;
        }
    }
    public static void main(String[] args) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        String s = "6 5 2 3 + 8 * + 3 + *";
        String[] strings = s.split(" ");
        for (int i = 0; i < strings.length; i++) {
            if (Character.isDigit(strings[i].charAt(0))) {
                stack.push(new TreeNode(strings[i]));
            } else {
                TreeNode root = new TreeNode(strings[i]);
                root.right = stack.pop();
                root.left = stack.pop();
                stack.push(root);
            }
        }
        BinaryTree binaryTree = new BinaryTree();
        System.out.println("中序递归");
        binaryTree.inOrder(stack.peek());
        System.out.println();
        System.out.println("中序非递归");
        binaryTree.noRecInOrder(stack.peek());
        System.out.println();
        System.out.println("后续递归");
        binaryTree.postOrder(stack.peek());
        System.out.println();
        System.out.println("后续非递归");
        binaryTree.noRecPostOrder(stack.peek());
        System.out.println();
        System.out.println("前序递归");
        binaryTree.preOrder(stack.peek());
        System.out.println();
        System.out.println("前序非递归");
        binaryTree.noRecPreOrder(stack.peek());
    }
}

测试

中序递归
6*5+2+3*8+3
中序非递归
6*5+2+3*8+3
后续递归
6523+8*+3+*
后续非递归
6523+8*+3+*
前序递归
*6++5*+2383
前序非递归
*6++5*+2383

中缀理应有括号,为了简单不写了。

二叉树

标签:结构   adc   highlight   a*   data   先序   中间   vat   markdown   

原文地址:https://www.cnblogs.com/dajunjun/p/11712791.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!