下面通过一个实例来简单实现下二叉树的常见操作
创建一个树结构TreeNode类:
/**
* 二叉树结构 - 子节点
*/
public class TreeNode {
Object data;//泛型数据对象
TreeNode lchild;//左子节点
TreeNode rchild;//右子节点
//默认构造方法
public TreeNode(Object data,TreeNode lchild,TreeNode rchild) {
this.data = data;
this.lchild = lchild;
this.rchild = rchild;
}
//不传参数,就调用默认上面的默认构造方法
public TreeNode(){
this(null,null,null);
}
//只传data参数,就调用默认上面的默认构造方法
public TreeNode(Object data){
this(data,null,null);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("TreeNode{");
sb.append("data=").append(data);
if(lchild != null)
sb.append(", lchild=").append(lchild);
if(rchild != null)
sb.append(", rchild=").append(rchild);
sb.append('}');
return sb.toString();
}
}
对二叉树的各种操作具体实现OptionTree类
import java.util.*;
/**
* 二叉树的操作
*/
public class OptionTree {
//1.1前序遍历,递归实现
public void preorder1(TreeNode root){
if(root != null){
System.out.print(root.data+"\t");
preorder1(root.lchild);
preorder1(root.rchild);
}
}
//1.2前序遍历,迭代和栈实现
public void preorder2(TreeNode root){
if(root != null){
Stack<TreeNode> stack = new Stack<>();
stack.push(root);//初始化,先将头结点入栈
while (!stack.isEmpty()){
root = stack.pop();
System.out.print(root.data+"\t");//打印根节点或者右节点
while (root != null){
if(root.lchild != null)
System.out.print(root.lchild.data+"\t");//打印左节点
if(root.rchild != null)
stack.push(root.rchild);//右节点入栈
root = root.lchild;//遍历左节点直到为最后一个左节点
}
}
}
}
//2.1中序遍历,递归实现
public void inorder1(TreeNode root){
if(root != null){
inorder1(root.lchild);
System.out.print(root.data+"\t");
inorder1(root.rchild);
}
}
//2.2中序遍历,迭代和栈实现
public void inorder2(TreeNode root){
if(root !=null){
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.empty()){//遍历右子树
while(root != null){//每次遍历将左子树入栈
stack.push(root);
root = root.lchild;
}
root = stack.pop();
System.out.print(root.data+"\t");
root = root.rchild;
}
}
}
//3.1后序遍历,递归实现
public void backorder1(TreeNode root){
if(root != null){
backorder1(root.lchild);
backorder1(root.rchild);
System.out.print(root.data+"\t");
}
}
//3.2后序遍历,迭代和栈实现
public void backorder2(TreeNode root){
Stack<TreeNode> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
int i = 1;
while(root != null || !stack1.empty())
{
while (root != null)
{
stack1.push(root);
stack2.push(0);
root = root.lchild;
}
while(!stack1.empty() && stack2.peek() == i)
{
stack2.pop();
System.out.print(stack1.pop().data + "\t");
}
if(!stack1.empty())
{
stack2.pop();
stack2.push(1);
root = stack1.peek();
root = root.rchild;
}
}
}
//4 层序遍历 - 使用队列来存储每一层的左右子结点
public void levelorder(TreeNode root){
if(root != null){
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);//最开始将头结点添加到队列
while (!queue.isEmpty()){
//每次取出队列头部元素,并更新root的最新位置
root = queue.poll();
System.out.print(root.data+"\t");
if(root.lchild != null)
queue.offer(root.lchild);
if(root.rchild != null)
queue.offer(root.rchild);
}
}
}
// 使用前序遍历查找指定结点
public void searchBypreorder(TreeNode root,Object data){
if(root != null){
if(root.data == data){
System.out.println("找到该节点:"+root);
return;
}
searchBypreorder(root.lchild,data);
searchBypreorder(root.rchild,data);
}
}
// 使用前序遍历统计结点个数
public int countNodesBypreorder(TreeNode root){
int count = 0;
if(root != null){
count++;//遍历到当前结点,就+1
count += countNodesBypreorder(root.lchild);//遍历左节点,最终个数加到count
count += countNodesBypreorder(root.rchild);//遍历右节点,最终个数加到count
}
return count;
}
// 求二叉树的深度 - 递归实现
public int getDeep1(TreeNode root){
if(root!=null){
int left = getDeep1(root.lchild);
int right = getDeep1(root.rchild);
return left>right ? left+1 : right+1;
}
return 0;
}
/**
* 求二叉树的深度 - 广度优先迭代实现
* 参考层序遍历,每遍历一层,变量+1
*/
public int getDeep2(TreeNode root){
if(root !=null){
int res = 0;//记录层数
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
while (size > 0){
TreeNode nowfloor = queue.poll();//当前层的第一个结点
if(nowfloor.lchild!= null)
queue.offer(nowfloor.lchild);
if(nowfloor.rchild != null)
queue.offer(nowfloor.rchild);
size--;
}
res++;//当前层遍历完,层数就+1
}
return res;
}
return 0;
}
}
测试类:Test
/**
* 假设二叉树结构如下
* 50
* / \
* 45 70
* / \ / \
* 30 55 65 80
* / \
* 20 25
*/
public class Test {
public static void main(String[] args) {
//初始化各节点
TreeNode treeNode5 = new TreeNode(55);
TreeNode treeNode6 = new TreeNode(65);
TreeNode treeNode7 = new TreeNode(80);
TreeNode treeNode8 = new TreeNode(20);
TreeNode treeNode9 = new TreeNode(25);
//给四个有子结点的进行赋值的同时赋值子结点
TreeNode treeNode4 = new TreeNode(30,treeNode8,treeNode9);
TreeNode treeNode3 = new TreeNode(70,treeNode6,treeNode7);
TreeNode treeNode2 = new TreeNode(45,treeNode4,treeNode5);
TreeNode root = new TreeNode(50,treeNode2,treeNode3);
OptionTree optionTree = new OptionTree();
// optionTree.preorder1(root);
// System.out.println("");
// optionTree.preorder2(root);
// System.out.println("");
// optionTree.inorder1(root);
// System.out.println("");
// optionTree.inorder2(root);
// System.out.println("");
// optionTree.backorder1(root);
// System.out.println("");
// optionTree.backorder2(root);
// System.out.println("");
// optionTree.levelorder(root);
// optionTree.searchBypreorder(root,45);
// System.out.println( optionTree.countNodesBypreorder(root));
// System.out.println("\n"+optionTree.getDeep1(root));
// System.out.println(optionTree.getDeep2(root));
}
}