package com.gzsll.ds;
import java.util.Stack;
public class BinaryTree {
private static class BinaryTreeNode {
BinaryTreeNode lChild, rChild;
Object data;
public BinaryTreeNode(Object data, BinaryTreeNode lChild,
BinaryTreeNode rChild) {
this.data = data;
this.rChild = rChild;
this.lChild = lChild;
}
public BinaryTreeNode(Object data) {
this(data, null, null);
}
public BinaryTreeNode() {
}
public BinaryTreeNode getlChild() {
return lChild;
}
public void setlChild(BinaryTreeNode lChild) {
this.lChild = lChild;
}
public BinaryTreeNode getrChild() {
return rChild;
}
public void setrChild(BinaryTreeNode rChild) {
this.rChild = rChild;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
public static BinaryTreeNode createTree(String exp) {
BinaryTreeNode[] nodes = new BinaryTreeNode[3];
BinaryTreeNode b, p = null;
int top = -1, k = 0, j = 0;
char[] exps = exp.toCharArray();
char data = exps[j];
b = null;
while (j < exps.length - 1) {
switch (data) {
case '(':
top++;
nodes[top] = p;
k = 1;
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
default:
p = new BinaryTreeNode(data, null, null);
if (b == null) {
b = p;
} else {
switch (k) {
case 1:
nodes[top].setlChild(p);
break;
case 2:
nodes[top].setrChild(p);
break;
}
}
}
j++;
data = exps[j];
}
return b;
}
/**
* 递归实现先序遍历
*
* @param node
*/
public void PreOrder(BinaryTreeNode node) {
if (node == null) {
return;
} else {
System.out.print(node.getData() + " ");
PreOrder(node.getlChild());
PreOrder(node.getrChild());
}
}
/**
* 递归实现中序遍历
*
* @param node
*/
public void InOrder(BinaryTreeNode node) {
if (node == null) {
return;
} else {
InOrder(node.getlChild());
System.out.print(node.getData() + " ");
InOrder(node.getrChild());
}
}
/**
* 递归实现后序遍历
*
* @param node
*/
public void PostOrder(BinaryTreeNode node) {
if (node == null) {
return;
} else {
PostOrder(node.getlChild());
PostOrder(node.getrChild());
System.out.print(node.getData() + " ");
}
}
/**
* 非递归前序遍历 对于任一结点P:
*
* 1)访问结点P,并将结点P入栈;
*
* 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,
* 则将P的左孩子置为当前的结点P;
*
* 3)直到P为NULL并且栈为空,则遍历结束。
*/
public void PreOrder2(BinaryTreeNode node) {
Stack<BinaryTreeNode> s = new Stack<BinaryTree.BinaryTreeNode>();
while (node != null || !s.isEmpty()) {
while (node != null) {
System.out.print(node.getData() + " ");
s.push(node);
node = node.getlChild();
}
while (!s.isEmpty()) {
node = s.pop();
node = node.getrChild();
}
}
}
/**
* 非递归实现中序遍历
* 1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
*
* 2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
*
* 3)直到P为NULL并且栈为空则遍历结束
*/
public void InOrder2(BinaryTreeNode node) {
Stack<BinaryTreeNode> s = new Stack<BinaryTree.BinaryTreeNode>();
while (node != null || !s.isEmpty()) {
while (node != null) {
s.push(node);
node = node.getlChild();
}
while (!s.isEmpty()) {
node = s.pop();
System.out.print(node.getData() + " ");
node = node.getrChild();
}
}
}
/**
* 后序遍历 要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;
* 或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,
* 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
*
*/
public void PostOrder2(BinaryTreeNode node) {
Stack<BinaryTreeNode> s = new Stack<BinaryTree.BinaryTreeNode>();
BinaryTreeNode cur;
BinaryTreeNode pre = null;
s.push(node);
while (!s.isEmpty()) {
cur = s.peek();
if ((cur.getlChild() == null && cur.getrChild() == null)
|| (pre != null && (pre == cur.getlChild() || pre == cur
.getrChild()))) {
System.out.print(cur.getData() + " ");
s.pop();
pre = cur;
} else {
if(cur.getrChild()!=null){
s.push(cur.getrChild());
}
if(cur.getlChild()!=null){
s.push(cur.getlChild());
}
}
}
}
public static void main(String args[]){
String expression = "A(B(D(,G)),C(E,F))";
BinaryTreeNode node = BinaryTree.createTree(expression);
BinaryTree binaryTree = new BinaryTree();
System.out.println("前序遍历");
binaryTree.PreOrder(node);
System.out.println();
binaryTree.PreOrder2(node);
System.out.println("中序遍历");
binaryTree.InOrder(node);
System.out.println();
binaryTree.InOrder2(node);
System.out.println("后序遍历");
binaryTree.PostOrder(node);
System.out.println();
binaryTree.PostOrder2(node);
}
}
二叉树java实现
最新推荐文章于 2022-11-17 09:20:12 发布