表达式二叉树的定义:
表达式:1+2-95+4。(这里举例用的是简单的加减法)
需要将数字放在叶子节点,将操作符放在分支节点,就构成了一个二叉树,由于存储的是一个表达式,称之为“表达式二叉树”。
这个二叉树是怎么建立的呢?
首先将表达式中的数字和运算符取出来分别存入数字节点链表和运算符节点链表中去;
之后从数字链表中取出前两个节点,从运算符节点数组中取出第一个节点,将前面取出的两个数字节点分别作为运算符节点的左节点和右节点。最后将这个运算符节点加入数字节点中的第一个位置。在运算符没被取完的前提下,重复以上的步骤;
建立好了一个二叉树之后,现在来对这个二叉树进行遍历。
先序遍历
先序遍历的规则:
(1)根节点
(2)左节点
(3)右节点
拿上面画的图作例子:
首先访问的是根节点,然后遍历左子树,最后遍历右子树,在遍历左右子树的时候,仍然最先访问根节点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。
以上二叉树遍历结果就是:
-
-
- 1 2 95 4
-
中序遍历
中序遍历的规则:
(1)左节点
(2)根节点
(3)右节点
首先遍历左子树,然后访问根节点,最后遍历右子树,若二叉树为空则返回;
以上二叉树的遍历结果就是:
1+2-95+4
后序遍历
后序遍历的规则:
(1)左节点
(2)右节点
(3)根节点
首先遍历左子树,然后遍历右子树,最后访问根节点,在遍历左右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根节点,直到二叉树为空返回。
以上二叉树遍历的结果是:
1 2 + 95 - 4 +
下面来用Java写一下这个表达式二叉树的建立和各种遍历
(一)首先定义一个节点Node类:
节点所包含的内容有数据项,左子节点和右子节点,还需要定义一些方法来返回左节点和右节点和设置左节点和右节点。
(二)定义一个二叉树的类:
首先定义一个方法将表达式字符串中的数字和运算符进行分开,分别存入数字节点链表和运算符节点链表中去。
这里用到了String类的charAt方法,类似于数组,根据位置取出字符串中的某个字符,这里需要用它来将字符串中的字符一个一个取出来进行数字与否的判断;
部分代码如下:
//将字符串str中的数字字符和运算符字符分离
for(int i=0;i<str.length();i++) {
char ch = str.charAt(i);//根据字符位置,取出str字符串中的各个字符
if(ch>='0' && ch<='9') {//如果取出来的是数字字符则存储在数字数组节点中去
s+=ch;//为了实现双位数的输出
}else {//如果是其他字符则存储在运算符数组节点中去
Node node1 = new Node(s);
numlist.add(node1);
System.out.println("数字data---> "+node1.getData());
Node node = new Node(ch);
operlist.add(node);
System.out.println("运算符data---> "+node.getData());
s="";
}
}
Node node2 = new Node(s);
numlist.add(node2);//添加最后一个数字
然后进行表达式二叉树的建立:
首先从数字数组节点链表中取出前两个节点,再从运算符节点链表中取出第一个节点;
将取出的两个数字节点作为取出的运算符节点的左节点和右节点,然后将这个运算符节点存入数字节点链表中去;
重复以上步骤直到运算符节点链表中没有了节点。
这部分代码如下:
//将字符串str中的数字字符和运算符字符分离
for(int i=0;i<str.length();i++) {
char ch = str.charAt(i);//根据字符位置,取出str字符串中的各个字符
if(ch>='0' && ch<='9') {//如果取出来的是数字字符则存储在数字数组节点中去
s+=ch;//为了实现双位数的输出
}else {//如果是其他字符则存储在运算符数组节点中去
Node node1 = new Node(s);
numlist.add(node1);
System.out.println("数字data---> "+node1.getData());
Node node = new Node(ch);
operlist.add(node);
System.out.println("运算符data---> "+node.getData());
s="";
}
}
Node node2 = new Node(s);
numlist.add(node2);//添加最后一个数字
表达式二叉树建立好了以后,现在进行先序遍历,中序遍历,后序遍历
代码如下:(这里用的是递归)
//将刚刚生成的二叉树进行先序遍历 --根--左--右--
public void PreOrder(Node node) {
System.out.print(node.getData()+" --> ");//输出根节点内容
if(node.getLeft() != null) {
PreOrder(node.getLeft());
}
if(node.getRight() != null) {
PreOrder(node.getRight());
}
}
//将刚刚生成的二叉树进行中序遍历 --左--根--右--
public void InOrder(Node node) {
if(node.getLeft() != null) {
InOrder(node.getLeft());//一直向左,直到找到左节点为空的节点,输出该节点
}
System.out.print(node.getData()+" --> ");
if(node.getRight() != null) {
InOrder(node.getRight());
}
}
//将刚刚生成的二叉树进行后序遍历 --左--右--根--
public void PostOrder(Node node) {
if(node.getLeft() != null) {
PostOrder(node.getLeft());
}
if(node.getRight() != null) {
PostOrder(node.getRight());
}
System.out.print(node.getData()+" --> ");
}
源代码
节点类:
package 表达式二叉树;
/**
* 首先创建节点类
* @author HP
*
*/
public class Node {
private Object data;//数据类型任意
private Node left;//左节点
private Node right;//右节点
//构造函数 1,用于创建空节点
public Node() {
}
//构造函数 2,根据数据来创建节点
public Node(Object data) {
super();
this.data = data;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
//返回左节点
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
//返回右节点
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
二叉树类:
package 表达式二叉树;
import java.util.ArrayList;
public class Binary_Tree {
private Node root;//根节点
private String s = "";
//声明一个存储数字的数组节点
private static ArrayList<Node> numlist = new ArrayList<Node>();
//声明一个存储运算符的数组节点
private static ArrayList<Node> operlist = new ArrayList<Node>();
public void classify(String str) {
//将字符串str中的数字字符和运算符字符分离
for(int i=0;i<str.length();i++) {
char ch = str.charAt(i);//根据字符位置,取出str字符串中的各个字符
if(ch>='0' && ch<='9') {//如果取出来的是数字字符则存储在数字数组节点中去
s+=ch;//为了实现双位数的输出
}else {//如果是其他字符则存储在运算符数组节点中去
Node node1 = new Node(s);
numlist.add(node1);
System.out.println("数字data---> "+node1.getData());
Node node = new Node(ch);
operlist.add(node);
System.out.println("运算符data---> "+node.getData());
s="";
}
}
Node node2 = new Node(s);
numlist.add(node2);//添加最后一个数字
System.out.println("数字data---> "+node2.getData());
System.out.println();
System.out.println();
System.out.println("------输出数字节点数组中的内容------");
for(int i=0;i<numlist.size();i++) {
System.out.println(numlist.get(i).getData());
}
System.out.println();
System.out.println();
System.out.println("------输出运算符节点数组中的内容------");
for(int i=0;i<operlist.size();i++) {
System.out.println(operlist.get(i).getData());
}
while(operlist.size()>0) {
Node left = numlist.remove(0);//remove返回从列表中移除的元素
//***注意这里将前一个节点移除之后,取下一个节点的时候仍然是从0节点开始取***
Node right = numlist.remove(0);
//从运算符数组节点中取出第0个
Node oper = operlist.remove(0);
//将取出的第0个数字节点作为取出来的第0个运算符节点的左节点,
//取出的第1个数字节点作为取出来的第0个运算符节点的右节点
oper.setLeft(left);
oper.setRight(right);
//将以上取出来的三个节点组成的小树作为数字节点存入数字节点数组中的第0位
numlist.add(0,oper);
//循环,直到最后数字节点数组仅有一个节点,该节点即为根节点
}
//根节点即为最后一个数字节点
root = numlist.get(0);
}
public void show() {
System.out.println();
System.out.println();
//调用函数进行先序遍历
System.out.println("-----先序遍历----");
//前缀表达式
PreOrder(root);
System.out.println();
System.out.println();
//中缀表达式
System.out.println("-----中序遍历----");
InOrder(root);
System.out.println();
System.out.println();
//后缀表达式
System.out.println("-----后序遍历----");
PostOrder(root);
}
//将刚刚生成的二叉树进行先序遍历 --根--左--右--
public void PreOrder(Node node) {
System.out.print(node.getData()+" --> ");//输出根节点内容
if(node.getLeft() != null) {
PreOrder(node.getLeft());
}
if(node.getRight() != null) {
PreOrder(node.getRight());
}
}
//将刚刚生成的二叉树进行中序遍历 --左--根--右--
public void InOrder(Node node) {
if(node.getLeft() != null) {
InOrder(node.getLeft());//一直向左,直到找到左节点为空的节点,输出该节点
}
System.out.print(node.getData()+" --> ");
if(node.getRight() != null) {
InOrder(node.getRight());
}
}
//将刚刚生成的二叉树进行后序遍历 --左--右--根--
public void PostOrder(Node node) {
if(node.getLeft() != null) {
PostOrder(node.getLeft());
}
if(node.getRight() != null) {
PostOrder(node.getRight());
}
System.out.print(node.getData()+" --> ");
}
}
测试类:
package 表达式二叉树;
public class Test {
public static void main(String[] args) {
Binary_Tree bt = new Binary_Tree();
bt.classify("1+2-95+4");
bt.show();
}
}