二叉树:由一个根节点和左右孩子节点组成,左孩子和右孩子节点可以为空。在二叉树中,有前序遍历、中序遍历、后序遍历三种遍历方式。因为二叉树的孩子节点又是一个新的节点,同时也存在左孩子、右孩子,所以适合使用递归的方式来遍历。
下面先来写一下节点的定义和初始化一下节点:
char value;//存放数据
BinaryCharTree leftChild;//左孩子
BinaryCharTree rightChild;//右孩子
//定义结构
public BinaryCharTree(char paraName) {
value = paraName;
leftChild = null;
rightChild = null;
}
写一个用来测试的树,有7个节点,(手画出来更直观表现这棵树)
public static BinaryCharTree manualConstructTree() {
// 创建一个只有一个节点的树
BinaryCharTree resultTree = new BinaryCharTree('a');
// 创建多个节点,上面那个节点为根节点
// BinaryCharTreeNode tempTreeA = resultTree.root;
BinaryCharTree tempTreeB = new BinaryCharTree('b');
BinaryCharTree tempTreeC = new BinaryCharTree('c');
BinaryCharTree tempTreeD = new BinaryCharTree('d');
BinaryCharTree tempTreeE = new BinaryCharTree('e');
BinaryCharTree tempTreeF = new BinaryCharTree('f');
BinaryCharTree tempTreeG = new BinaryCharTree('g');
//把节点连接起来
resultTree.leftChild = tempTreeB;
resultTree.rightChild = tempTreeC;
tempTreeB.rightChild = tempTreeD;
tempTreeC.leftChild = tempTreeE;
tempTreeD.leftChild = tempTreeF;
tempTreeD.rightChild = tempTreeG;
return resultTree;
}
前序遍历(先根遍历)
递归要注意结束递归的条件,当左右孩子为空时就结束。递归代码非常简单。
public void preOrderVisit() {
System.out.print("" + value + " ");
//输出
if (leftChild != null) {
leftChild.preOrderVisit();
} //左孩子不为空,先序遍历左孩子
if (rightChild != null) {
rightChild.preOrderVisit();
} //右孩子不为空,先序遍历右孩子
}
中序遍历(中根遍历)
public void inOrderVisit() {
if (leftChild != null) {
leftChild.inOrderVisit();
} //左孩子不为空,进行中序遍历
System.out.print("" + value + " ");
//输出
if (rightChild != null) {
rightChild.inOrderVisit();
} // 右孩子不为空,进行中序遍历
}
后序遍历(后根遍历)
public void postOrderVisit() {
if (leftChild != null) {
leftChild.postOrderVisit();
} // 左孩子非空,进行后序遍历
if (rightChild != null) {
rightChild.postOrderVisit();
} // 右孩子非空,进行后序遍历
System.out.print("" + value + " ");//输出
}
判断树的高度(深度)
同样使用递归,分别判断左右子树(孩子)的高度。
public int getDepth() {
// It is a leaf.
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // 左右孩子都空,树高为1
// 判断左孩子的树高
int tempLeftDepth = 0;
if (leftChild != null) {
tempLeftDepth = leftChild.getDepth();//递归
}
// 判断右孩子的树高
int tempRightDepth = 0;
if (rightChild != null) {
tempRightDepth = rightChild.getDepth();//递归
}
if (tempLeftDepth >= tempRightDepth) {
return tempLeftDepth + 1;
} else {
return tempRightDepth + 1;
} // 左右树高进行比较,加上根节点的高度1
}
获取树中的节点数
同样使用递归,对左右子树分别进行节点数统计。
public int getNumNodes() {
// It is a leaf.
if ((leftChild == null) && (rightChild == null)) {
return 1;
} // Of if
// The number of nodes of the left child.
int tempLeftNodes = 0;
if (leftChild != null) {
tempLeftNodes = leftChild.getNumNodes();
} // Of if
// The number of nodes of the right child.
int tempRightNodes = 0;
if (rightChild != null) {
tempRightNodes = rightChild.getNumNodes();
} // Of if
// The total number of nodes.
return tempLeftNodes + tempRightNodes + 1;
}
main方法测试
public static void main(String args[]) {
BinaryCharTree tempTree = manualConstructTree();
System.out.println("\r\nPreorder visit:");
tempTree.preOrderVisit();
System.out.println("\r\nIn-order visit:");
tempTree.inOrderVisit();
System.out.println("\r\nPost-order visit:");
tempTree.postOrderVisit();
System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
System.out.println("The number of nodes is: " + tempTree.getNumNodes());
}
}
结果为和树为:
总结:发现利用递归对树操作十分的方便,也很容易理解。