要想遍历一个二叉树首先得有一个二叉树,我在实现的时候,一开始想着一个结点一个结点的添加,但是那样很麻烦,所以就提供了一个运用数组创建二叉树的方法。代码如下:
public class BinaryTree<T> {
//利用数组创建二叉树
private T[] nums ;
private BinaryTreeNode root;
//初始化二叉树
public BinaryTree() {
this.root = null;
}
//创建二叉树,用ArrayList记录,如果左右孩子都不为空则访问下一个结点,直到数组中内容全部被加进二叉树
public void createTree(T[] nums) {
if(nums.length==0) {
return;
}
BinaryTreeNode node = new BinaryTreeNode(nums[0]);
root = node;
ArrayList<BinaryTreeNode> list = new ArrayList<>();
for(int i=0 ; i<nums.length ; ) {
list.add(node);
if(list.get(0).getLeft()!=null&&list.get(0).getRight()!=null) {
list.remove(0);
} else if(list.get(0).getLeft()==null) {
i++;
if(i<nums.length) {
node = new BinaryTreeNode(nums[i]);
list.add(node);
list.get(0).setLeft(node);
} else {
break;
}
} else {
i++;
if(i<nums.length) {
node = new BinaryTreeNode(nums[i]);
list.add(node);
list.get(0).setRight(node);
} else {
break;
}
}
}
}
}
关于二叉树结点信息的代码如下:
public class BinaryTreeNode<T> {
private T data;
private BinaryTreeNode left = null;
private BinaryTreeNode right = null;
public BinaryTreeNode() { }
public BinaryTreeNode(T data) {
this.data = data;
}
……
}
- 前序遍历
- 递归实现
public void traverse(BinaryTree bTree) {
BinaryTreeNode root = bTree.getRoot();
if(root==null) {
return;
}
System.out.print(root.getData() + "\t");
BinaryTree leftTree = new BinaryTree();
leftTree.setRoot(root.getLeft());
traverse(leftTree);
BinaryTree rightTree = new BinaryTree();
rightTree.setRoot(root.getRight());
traverse(rightTree);
}
- 非递归实现
public void traverse(BinaryTree bTree) {
BinaryTreeNode node = bTree.getRoot();
Stack<BinaryTreeNode> stack = new Stack<>();
while(node!=null||stack.size()!=0) {
while(node!=null) { //一直向左访问直到没有左节点,打印出结点信息并压入栈
System.out.print(node.getData() + "\t");
stack.push(node);
node = node.getLeft();
}
if(stack.size()!=0) { //栈顶元素出栈并以相同的方式访问其右子树
node = stack.peek().getRight();
stack.pop();
}
}
}
- 中序遍历
- 递归实现
public void traverse(BinaryTree bTree) {
BinaryTreeNode root = bTree.getRoot();
if(root==null) {
return;
}
if(root.getLeft()!=null) {
BinaryTree leftTree = new BinaryTree();
leftTree.setRoot(root.getLeft());
traverse(leftTree);
}
System.out.print(root.getData() + "\t");
if(root.getRight()!=null) {
BinaryTree rightTree = new BinaryTree();
rightTree.setRoot(root.getRight());
traverse(rightTree);
}
}
- 非递归实现
public static void traverse(BinaryTree bTree) {
BinaryTreeNode node = bTree.getRoot();
Stack<BinaryTreeNode> stack = new Stack<>();
while(node!=null||stack.size()!=0) {
while(node!=null) {
stack.push(node);
node = node.getLeft();
}
if(stack.size()!=0) {
System.out.print(stack.peek().getData()+"\t");
node = stack.pop().getRight();
}
}
}
- 后序遍历
- 递归实现
public static void traverse(BinaryTree bTree) {
BinaryTreeNode root = bTree.getRoot();
if(root==null) {
return;
}
if(root.getLeft()!=null) {
BinaryTree leftTree = new BinaryTree();
leftTree.setRoot(root.getLeft());
traverse(leftTree);
}
if(root.getRight()!=null) {
BinaryTree rightTree = new BinaryTree();
rightTree.setRoot(root.getRight());
traverse(rightTree);
}
System.out.print(root.getData() + "\t");
}
- 非递归实现
思路:考虑到后序遍历的顺序是左、右、根,结合栈后进先出的特性,可以将根、右、左依此入栈,最后一次性弹出,即为后序遍历的结果。代码如下:
public static void traverse(BinaryTree bTree) {
BinaryTreeNode node = bTree.getRoot();
Stack<BinaryTreeNode> stack = new Stack<>();
Stack<BinaryTreeNode> result = new Stack<>();
while(stack.size()!=0||node!=null) {
while(node!=null) {
stack.push(node);
result.push(node);
node = node.getRight();
}
if(stack.size()!=0) {
node = stack.pop().getLeft();
}
}
while(result.size()!=0) {
System.out.print(result.peek().getData()+"\t");
result.pop();
}
}