一、树的节点
public class ThreeNode {
public Object data;
public ThreeNode leftChild;
public ThreeNode rightChild;
public ThreeNode(){
this(null);
}
public ThreeNode(Object data){
this(data,null,null);
}
public ThreeNode(Object data,ThreeNode leftChild, ThreeNode rightChild){
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
}
二、实现统计二叉树中的节点的个数的操作
思路:先声明一个计数变量count,若此节点非空,则count加1,统计此节点的左子树的节点个数,并且加入到count中,统计此节点的右子树的节点个数,并且加入到count中,最后返回count的值。
public class CountNode {
/**
* 深度优先(第一种方法)
*
* @param root
* @return
*/
public static int countNodeByDepth(ThreeNode root) {
int count = 0;
if (root == null) {
return 0;
} else {
count++;
count += countNodeByDepth(root.leftChild);
count += countNodeByDepth(root.rightChild);
}
return count;
}
/**
* 广度优先,借助队列(第二种方法)
*
* @param root
* @return
*/
public static int countNodeByWidth(ThreeNode root) {
Queue queue = new ConcurrentLinkedQueue();
int count = 0;
queue.offer(root);
while (!queue.isEmpty()) {
ThreeNode t = (ThreeNode) queue.poll();
count++;
if (t.leftChild != null) {
queue.offer(t.leftChild);
}
if (t.rightChild != null) {
queue.offer(t.rightChild);
}
}
return count;
}
/**
* 递归实现计算二叉树节点数,广度优先(第三种方法)
*
* @param root
* @return
*/
public static int countNode(ThreeNode root) {
if (root == null) {
return 0;
}
return countNode(root.leftChild) + countNode(root.rightChild) + 1;
}
}
三、判断两颗树是否相等
思路:若两棵树都为空,则两棵二叉树相等,返回true;若根节点相等,则继续判断他们的左子树是否相等,若左子树相等则继续判断他们的右子树是否相等,若右子树相等则判断两棵树相等,返回true。若还有其他情况,则返回false。
public class EqualThree {
/**
* 广度优先遍历
* @param a
* @param b
* @return
*/
public static boolean isEqualThree(ThreeNode a,ThreeNode b){
if ( a == null && b == null){
return true;
}
if (a != null && b != null){
if (a.data.equals(b.data)){
if (isEqualThree(a.leftChild,b.leftChild)){
if (isEqualThree(a.rightChild,b.rightChild)){
return true;
}
}
}
}
return false;
}
}
四、查找在二叉树中值为x的节点的操作
思路:若二叉树为空,则树中不存在这个节点,返回null;否则,将其与根节点进行比较,若相等则返回该节点;若根节点的值不与要查找的值相等,则继续比较根节点的左子树中进行查找,若找到则返回该节点;若在左子树中找不到该节点,则去右子树中寻找该节点;若在右子树中找到则返回该节点,若找不到则返回null。
public class SearchNode {
/**
* 查找树中是否存在节点x,若存在返回此节点,不存在返回null
* @param root
* @param x
* @return
*/
public static Object searchNode(ThreeNode root, Object x) {
if (root != null){
if (root.data == x) {
return x;
}else {
Object result = searchNode(root.leftChild,x);
return result != null? result:searchNode(root.rightChild,x);
}
}
return null;
}
}
五、求二叉树的深度
思路:若二叉树为空,则返回0,若不为空,则求左子树的深度,然后求右子树的深度,最后比较左子树的深度和右子树的深度那个更大,最后结果加1(默认根节点为第0层)。
public class ThreeDepth {
/**
* 深度优先
* @param root
* @return
*/
public static int getThreeDepth(ThreeNode root) {
if (root != null) {
int leftDepth = getThreeDepth(root.leftChild);
int rightDepth = getThreeDepth(root.rightChild);
return 1 + ((leftDepth > rightDepth) ? leftDepth : rightDepth);
}
return 0;
}
}
六、二叉树的遍历,先序遍历,中序遍历和后序遍历
public class TraverseThree {
/**
* 先序遍历
*
* @param root
*/
public void preTraverse(ThreeNode root) {
if (root != null) {
System.out.print(" " + root.data);
preTraverse(root.leftChild);
preTraverse(root.rightChild);
}
}
/**
* 中序遍历
*
* @param root
*/
public void inTraverse(ThreeNode root) {
if (root != null) {
inTraverse(root.leftChild);
System.out.print(" " + root.data);
inTraverse(root.rightChild);
}
}
/**
* 后序遍历
*
* @param root
*/
public void postTraverse(ThreeNode root) {
if (root != null) {
postTraverse(root.leftChild);
postTraverse(root.rightChild);
System.out.print(" " + root.data);
}
}
}