二叉树结点数据结构
public class TreeNode{
public int key = 0;
public String data = null;
public boolean isVisited = false;
public TreeNode leftChild = null;
public TreeNode rightChild = null;
public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}
初始化根节点
TreeNode root = null;
public javatest(){
root = new TreeNode(1,"root A");
}
创建二叉树
public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");
root.leftChild = newNodeB;
root.rightChild = newNodeC;
root.leftChild.leftChild = newNodeD;
root.leftChild.rightChild = newNodeE;
root.rightChild.rightChild = newNodeF;
}
访问节点
public void visted(TreeNode subTree) {
subTree.isVisited = true;
System.out.println("key:" + subTree.key + "--name:" + subTree.data);
}
递归与非递归进行前中后序遍历
前序遍历
// 前序遍历
public void preOrder(TreeNode subTree) {
if (subTree != null) {
visted(subTree);
preOrder(subTree.leftChild);
preOrder(subTree.rightChild);
}
}
非递归借助栈来实现
1.定义node来遍历二叉树,定义栈来储存二叉树结点
2.利用while循环,一开始node指向根节点,访问node,并入栈,将node更新为左子树,继续循环;当node为null时循环停止,此时node代表的是最左节点的左节点,为null时表示最左节点和其左子树打印完毕。
3.接下来需要打印左节点的右子树,取出栈顶元素,并将node更新为栈顶元素的右子树。
// 前序遍历的非递归实现
public void nonRecPreOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = root;
while (node != null || stack.size() > 0) {
while (node != null) {
visted(node);
stack.push(node);
node = node.leftChild;
}
while (stack.size() > 0) {
node = stack.pop();
node = node.rightChild;
}
}
}
中序遍历
// 中序遍历
public void inOrder(TreeNode subTree) {
if (subTree != null) {
inOrder(subTree.leftChild);
visted(subTree);
inOrder(subTree.rightChild);
}
}
非递归过程
1.定义node来遍历二叉树,定义栈来储存二叉树结点
2.利用while循环,一开始node指向根节点,入栈,然后将node更新为左子树,继续循环;直到node为null时第二层while循环停止,此时node代表最左节点的左节点。
3.接下来需要打印最左节点的左子树;因为左字树为空,所以直接打印他的根,取出栈顶元素,这就是最后一颗树的根,打印,删除栈顶结点,将node更新为栈顶元素的右结点;
// 中序遍历的非递归实现
public void nonRecInOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
TreeNode node = root;
while (node != null || stack.size() > 0) {
// 存在左子树
while (node != null) {
stack.push(node);
node = node.leftChild;
}
// 栈非空
if (stack.size() > 0) {
node = stack.pop();
visted(node);
node = node.rightChild;
}
}
}
后序遍历
// 后续遍历
public void postOrder(TreeNode subTree) {
if (subTree != null) {
postOrder(subTree.leftChild);
postOrder(subTree.rightChild);
visted(subTree);
}
}
非递归过程
1.循环将左子树左节点全部入栈
2.入栈结束,当前root为最左节点的左节点;当前节点无右子树或右子树已经输出,则访问当前节点后用node记录刚访问过的节点,root = stack.pop();更新root为栈内下一元素。
3.当前root有右子树时,右子树入栈,当前节点更新为节点的右子树。
// 后序遍历的非递归实现
public void noRecPostOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
TreeNode node = root;
while (root!= null) {
// 左子树入栈
for (; root.leftChild != null; root = root.leftChild) {
stack.push(root);
}
// 当前结点无右子树或右子树已经输出
while (root != null && (root.rightChild == null || root.rightChild == node)) {
visted(root);
// 纪录上一个已输出结点
node = root;
if (stack.empty())
return;
root = stack.pop();
}
// 处理右子树
stack.push(root);
root = root.rightChild;
}
}
完整测试
import java.util.Stack;
public class javatest {
TreeNode root = null;
public class TreeNode{
public int key = 0;
public String data = null;
public boolean isVisited = false;
public TreeNode leftChild = null;
public TreeNode rightChild = null;
public TreeNode(int key,String data){
this.key = key;
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
}
public javatest(){
root = new TreeNode(1,"root A");
}
public void createBinTree(TreeNode root){
TreeNode newNodeB = new TreeNode(2,"B");
TreeNode newNodeC = new TreeNode(3,"C");
TreeNode newNodeD = new TreeNode(4,"D");
TreeNode newNodeE = new TreeNode(5,"E");
TreeNode newNodeF = new TreeNode(6,"F");
root.leftChild = newNodeB;
root.rightChild = newNodeC;
root.leftChild.leftChild = newNodeD;
root.leftChild.rightChild = newNodeE;
root.rightChild.rightChild = newNodeF;
}
// 前序遍历
public void preOrder(TreeNode subTree) {
if (subTree != null) {
visted(subTree);
preOrder(subTree.leftChild);
preOrder(subTree.rightChild);
}
}
// 中序遍历
public void inOrder(TreeNode subTree) {
if (subTree != null) {
inOrder(subTree.leftChild);
visted(subTree);
inOrder(subTree.rightChild);
}
}
// 后续遍历
public void postOrder(TreeNode subTree) {
if (subTree != null) {
postOrder(subTree.leftChild);
postOrder(subTree.rightChild);
visted(subTree);
}
}
// 前序遍历的非递归实现
public void nonRecPreOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = p;
while (node != null || stack.size() > 0) {
while (node != null) {
visted(node);
stack.push(node);
node = node.leftChild;
}
while (stack.size() > 0) {
node = stack.pop();
node = node.rightChild;
}
}
}
// 中序遍历的非递归实现
public void nonRecInOrder(TreeNode p) {
Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
TreeNode node = p;
while (node != null || stack.size() > 0) {
// 存在左子树
while (node != null) {
stack.push(node);
node = node.leftChild;
}
// 栈非空
if (stack.size() > 0) {
node = stack.pop();
visted(node);
node = node.rightChild;
}
}
}
// 后序遍历的非递归实现
public void noRecPostOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<javatest.TreeNode>();
TreeNode node = root;
while (root!= null) {
// 左子树入栈
for (; root.leftChild != null; root = root.leftChild) {
stack.push(root);
}
// 当前结点无右子树或右子树已经输出
while (root != null && (root.rightChild == null || root.rightChild == node)) {
visted(root);
// 纪录上一个已输出结点
node = root;
if (stack.empty())
return;
root = stack.pop();
}
// 处理右子树
stack.push(root);
root = root.rightChild;
}
}
public void visted(TreeNode subTree) {
subTree.isVisited = true;
System.out.println("key:" + subTree.key + "--name:" + subTree.data);
}
// 测试
public static void main(String[] args) {
javatest bt = new javatest();
bt.createBinTree(bt.root);
System.out.println("*******(前序遍历)[ABDECF]遍历*****************");
bt.preOrder(bt.root);
System.out.println("*******(中序遍历)[DBEACF]遍历*****************");
bt.inOrder(bt.root);
System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");
bt.postOrder(bt.root);
System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");
bt.nonRecPreOrder(bt.root);
System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");
bt.nonRecInOrder(bt.root);
System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");
bt.noRecPostOrder(bt.root);
}
}
结果:
*******(前序遍历)[ABDECF]遍历*****************
key:1--name:root A
key:2--name:B
key:4--name:D
key:5--name:E
key:3--name:C
key:6--name:F
*******(中序遍历)[DBEACF]遍历*****************
key:4--name:D
key:2--name:B
key:5--name:E
key:1--name:root A
key:3--name:C
key:6--name:F
*******(后序遍历)[DEBFCA]遍历*****************
key:4--name:D
key:5--name:E
key:2--name:B
key:6--name:F
key:3--name:C
key:1--name:root A
***非递归实现****(前序遍历)[ABDECF]遍历*****************
key:1--name:root A
key:2--name:B
key:4--name:D
key:3--name:C
key:6--name:F
***非递归实现****(中序遍历)[DBEACF]遍历*****************
key:4--name:D
key:2--name:B
key:5--name:E
key:1--name:root A
key:3--name:C
key:6--name:F
***非递归实现****(后序遍历)[DEBFCA]遍历*****************
key:4--name:D
key:5--name:E
key:2--name:B
key:6--name:F
key:3--name:C
key:1--name:root A