二叉树的遍历分为三种方式:前序遍历,中序遍历,后序遍历,不了解的可参考前一篇文章:二叉树的遍历
先看手绘的一张二叉树的图片:
二叉树的深度的计算方式:length = log2m + 1,此处2为底数,m表示总的节点数,结果取整数;
注意,Java的Math中没有直接提供方法计算log2m,但我们可以做一步转换,转成log2N = logeN / loge2。
第m个数的左右孩子节点的下标分别为 层数 * 2 + 1,层数 * 2 + 2;
下面是Java具体的实现,主要是实现了二叉树的构建和三种遍历方式。
先声明一个二叉树节点对象:
package com.zxd.bean;
/**
* BinaryTreeNode:二叉树对象,包含当前节点值,左孩子结点,右孩子节点
*
* @author zeng.xiangdong 1770534116@qq.com
* @version V1.0 2014-7-14 下午10:03:57
*/
public class BinaryTreeNode {
private BinaryTreeNode leftChildNode;
private BinaryTreeNode rightChildNode;
private int data;
public BinaryTreeNode(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BinaryTreeNode getLeftChildNode() {
return leftChildNode;
}
public void setLeftChildNode(BinaryTreeNode leftChildNode) {
this.leftChildNode = leftChildNode;
}
public BinaryTreeNode getRightChildNode() {
return rightChildNode;
}
public void setRightChildNode(BinaryTreeNode rightChildNode) {
this.rightChildNode = rightChildNode;
}
}
再就是二叉树的具体实现:
package com.zxd.link;
import java.util.ArrayList;
import java.util.List;
import com.zxd.bean.BinaryTreeNode;
/**
* BinaryTreeTraverse:二叉树的遍历
*
* @author zeng.xiangdong 1770534116@qq.com
* @version V1.0 2014-7-14 下午10:08:32
*/
public class BinaryTreeTraverse {
/**
* create:二叉树的建立
*
* @param array 初始值数组
* @return List<BinaryTreeNode> 二叉树节点的集合
*/
private List<BinaryTreeNode> create(Integer[] array) {
// 存储二叉树结果集合
List<BinaryTreeNode> numList = new ArrayList<BinaryTreeNode>();
for(int num : array) {
numList.add(new BinaryTreeNode(num));
}
// 计算深度:没有直接转化log2N的方法,可转成log2N = logeN/loge2
// 将深度转成整形
int size = numList.size();
int length = (int)(Math.log(size) / Math.log(2)) + 1;
for(int i = 0; i < length; i++) {
int leftChildIndex = i * 2 + 1;
int rightChildIndex = i * 2 + 2;
// 考虑到不是完全二叉树,如果该节点大于初始化的长度,则返回
if(leftChildIndex <= size) {
numList.get(i).setLeftChildNode(numList.get(leftChildIndex));
} else {
return numList;
}
if(rightChildIndex <= size) {
numList.get(i).setRightChildNode(numList.get(rightChildIndex));
} else {
return numList;
}
} // end of for
BinaryTreeNode lastNode = numList.get(size - 1);
// 最后一个节点: 最后一个节点应该存放的位置,其父节点下标为 (size - 1)/2;
// 如果数组长度为复数,则最后一个节点为坐孩子节点,否则为右孩子节点;参考图片
int lastNodeIndex = (size - 1) / 2;
if(size % 2 == 0) {
numList.get(lastNodeIndex).setLeftChildNode(lastNode);
} else {
numList.get(lastNodeIndex).setRightChildNode(lastNode);
}
return numList;
}
/**
* dlrTraverse 前序遍历(DLR)
*
* @param node 要遍历的节点
*/
private void dlrTraverse(BinaryTreeNode node) {
if(node == null) {
return;
}
System.out.print(node.getData() + " ");
dlrTraverse(node.getLeftChildNode());
dlrTraverse(node.getRightChildNode());
}
/**
* dlrTraverse 中序遍历(LDR)
*
* @param node 要遍历的节点
*/
private void ldrTraverse(BinaryTreeNode node) {
if(node == null) {
return;
}
ldrTraverse(node.getLeftChildNode());
System.out.print(node.getData() + " ");
ldrTraverse(node.getRightChildNode());
}
/**
* dlrTraverse 后序遍历(LRD)
*
* @param node 要遍历的节点
*/
private void lrdTraverse(BinaryTreeNode node) {
if(node == null) {
return;
}
lrdTraverse(node.getLeftChildNode());
lrdTraverse(node.getRightChildNode());
System.out.print(node.getData() + " ");
}
// 测试main方法
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
BinaryTreeTraverse traverse = new BinaryTreeTraverse();
List<BinaryTreeNode> binaryTreeNodes = traverse.create(array);
BinaryTreeNode node = binaryTreeNodes.get(0);
// 前序遍历 DLR
traverse.dlrTraverse(node);
System.out.println("-------------------------");
// 中序遍历 LDR
traverse.ldrTraverse(node);
System.out.println("-------------------------");
// 后序遍历 LRD
traverse.lrdTraverse(node);
System.out.println("-------------------------");
}
}
输出结果: