赞
踩
树型结构是一类特别重要的非线性结构,其中以树和二叉树最为常用。
节点的度:结点拥有的子树个数称为结点的度。例如第一个图,根结点A的度为3,结点B的度为2,结点C的度为1,结点F的度为0
叶子:度为0的结点称为叶子或终端节点
树的深度:树中结点的最大层次,第一个图中树的深度为4
满二叉树:一棵深度为k且有2^k-1个结点的二叉树称为满二叉树。
完全二叉树:将深度为k的满二叉树结点进行连续编号。若有结点为n,深度为k,且1~n个结点与满二叉树一一对应的二叉树,称之为完全二叉树。
遍历最简单的写法就是递归写法,但递归层数多了时间复杂度会很大,而且仔细思考后,你会发现递归的过程其实就像一个栈后入先出的过程
所以我们可以利用栈写出非递归版的二叉树遍历,这里解释下思路
下图为代码中写死的二叉树
import java.util.Stack;
/**
* 二叉树
*/
public class BinaryTree {
/** 根结点 */
public BiTNode root;
/** 结点 */
static public class BiTNode {
public BiTNode lefNode; // 左结点
public BiTNode riNode; // 右结点
public String data; // 结点内容
public BiTNode() {
}
public BiTNode(String data) {
this.data = data;
}
}
/**
* 默认创造一个写死的二叉树
*/
public void createBiTree() {
BiTNode b1 = new BiTNode("-");
BiTNode b2 = new BiTNode("+");
BiTNode b3 = new BiTNode("/");
BiTNode b4 = new BiTNode("a");
BiTNode b5 = new BiTNode("*");
BiTNode b6 = new BiTNode("e");
BiTNode b7 = new BiTNode("f");
BiTNode b8 = new BiTNode("b");
BiTNode b9 = new BiTNode("-");
BiTNode b10 = new BiTNode("c");
BiTNode b11 = new BiTNode("d");
this.root = b1;
b1.lefNode = b2;
b1.riNode = b3;
b2.lefNode = b4;
b2.riNode = b5;
b3.lefNode = b6;
b3.riNode = b7;
b5.lefNode = b8;
b5.riNode = b9;
b9.lefNode = b10;
b9.riNode = b11;
}
/**
* 递归先序,每次都先输出访问结点的内容,再先序遍历左结点,然后右结点
*
* @param rNode
*/
public void preOrderTraverse(BiTNode rNode) {
if (rNode == null)
return;
System.out.print(rNode.data);
preOrderTraverse(rNode.lefNode);
preOrderTraverse(rNode.riNode);
}
/**
* 递归中序,先中序左结点,再输出根结点内容,最后中右结点
*
* @param rNode
*/
public void inOrderTraverse(BiTNode rNode) {
if (rNode == null)
return;
inOrderTraverse(rNode.lefNode);
System.out.print(rNode.data);
inOrderTraverse(rNode.riNode);
}
/**
* 递归后序,后序左结点,后序右结点,输出根结点内容
*
* @param rNode
*/
public void postOrderTraverse(BiTNode rNode) {
if (rNode == null)
return;
postOrderTraverse(rNode.lefNode);
postOrderTraverse(rNode.riNode);
System.out.print(rNode.data);
}
/**
* 非递归先序
*/
public void preOrder() {
//建立一个空栈
Stack<BiTNode> stack = new Stack<BinaryTree.BiTNode>();
//设置当前结点为根结点
BiTNode node = root;
//若当前结点不为空或栈不为空
while (!stack.isEmpty() || node != null) {
//一直走到当前结点的最左侧,边走边输出结点值
while (node != null) {
//输出结点内容
System.out.print(node.data);
//将该结点放入栈
stack.push(node);
//设置当前结点为目前结点的左结点
node = node.lefNode;
}
//如果栈未空,弹出栈内结点,设置当前结点为弹出结点的右结点
if (!stack.isEmpty()) {
node = stack.pop();
node = node.riNode;
}
}
System.out.println();
}
/**
* 非递归中序
*/
public void inOrder() {
//建立一个空栈
Stack<BiTNode> stack = new Stack<BinaryTree.BiTNode>();
//设置当前结点为根结点
BiTNode node = root;
//若当前结点不为空或栈不为空
while (!stack.isEmpty() || node != null) {
//一直走到当前结点的最左侧,边走边入栈
while (node != null) {
stack.push(node);
node = node.lefNode;
}
//如果栈不为空,弹栈,输出弹出结点的值,设置当前结点为弹出结点的右结点
if (!stack.isEmpty()) {
node = stack.pop();
System.out.print(node.data);
node = node.riNode;
}
}
System.out.println();
}
/**
* 非递归后序
*/
public void postOrder() {
//建立一个栈,压入根结点
Stack<BiTNode> stack = new Stack<BinaryTree.BiTNode>();
stack.push(root);
//访问的前一个结点
BiTNode preNode = null;
//访问的当前结点
BiTNode node = null;
//当栈不为空时
while (!stack.isEmpty()) {
//设置当前结点为栈中最后一个压入的结点
node = stack.lastElement();
//后序遍历时,一个结点只有左右子树都为空,或者左右结点已经被访问过才会访问它(需要设置一个前结点来确认左右结点是否访问)
if (node.lefNode == null
&& node.riNode == null
|| (preNode != null && (preNode == node.lefNode || preNode == node.riNode))) {
System.out.print(node.data);
stack.pop();
preNode = node;
}
//否则,把该结点的左右结点压入栈中
else {
//先压右结点入栈
if (node.riNode != null)
stack.push(node.riNode);
//后压左结点入栈,确保下一次循环的当前结点为左结点
if (node.lefNode != null)
stack.push(node.lefNode);
}
}
System.out.println();
}
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.createBiTree();
System.out.println("先序:");
binaryTree.preOrderTraverse(binaryTree.root);
System.out.println();
binaryTree.preOrder();
System.out.println("-----------------");
System.out.println("中序:");
binaryTree.inOrderTraverse(binaryTree.root);
System.out.println();
binaryTree.inOrder();
System.out.println("-----------------");
System.out.println("先序:");
binaryTree.postOrderTraverse(binaryTree.root);
System.out.println();
binaryTree.postOrder();
System.out.println("-----------------");
}
}/**output:
先序:
-+a*b-cd/ef
-+a*b-cd/ef
-----------------
中序:
a+b*c-d-e/f
a+b*c-d-e/f
-----------------
先序:
abcd-*+ef/-
abcd-*+ef/-
-----------------
*/

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。