二叉树的概念和常用术语介绍:
二叉树:每个节点最多有两个子树的树结构。
根节点:一棵树最上面的节点称为根节点。
父节点,子节点:如果一个节点下面连接多个节点,那么该节点称为父节点。它下面的节点称为子节点。
叶子节点(树叶):没有任何子节点的节点称为叶子节点。
兄弟节点:具有相同父节点的节点互称为兄弟节点。
节点度:节点拥有的子树数。
树的深度:从根节点开始(其深度为0)自顶向下逐层累加的。(从书中看到)
树的高度:从叶子节点开始(其高度为0)自底向上逐层累加的。(从书中看到)
注意:有些说法中树中结点的最大层次称之为树的深度或者高度
创建节点对象并实现一些操作:
public class HeroNode {
private Integer no;
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode(Integer no, String name, HeroNode left, HeroNode right) {
this.no = no;
this.name = name;
this.left = left;
this.right = right;
}
public HeroNode(Integer no, String name) {
this.no = no;
this.name = name;
}
//前序遍历
public void prefixOrder(){
System.out.println("输出当前节点:" + this); //输出父节点
//有左子节点就递归
if (this.left != null){
this.left.prefixOrder();
}
//有右子节点就递归
if (this.right != null){
this.right.prefixOrder();
}
}
//中序遍历
public void infixOrder(){
if (this.left != null){
this.left.infixOrder();
}
System.out.println("输出当前节点:" + this);
if (this.right != null){
this.right.infixOrder();
}
}
//后序遍历
public void suffixOrder(){
//有左子节点就递归
if (this.left != null){
this.left.suffixOrder();
}
//有右子节点就递归
if (this.right != null){
this.right.suffixOrder();
}
System.out.println("输出当前节点:" + this);
}
//前序查找
public HeroNode prefixSearch(int no){
//根
if (this.no == no){
//System.out.println("找到了no="+no+"的节点:" + this);
return this;
}
HeroNode temp = null;
//左递归
if (this.left != null){
temp = this.left.prefixSearch(no);
}
//说明左子树找到了
if (temp != null){
return temp;
}
//右递归
if (this.right != null){
temp = this.right.prefixSearch(no);
}
return temp;
}
//中序查找
public HeroNode infixSearch(int no){
HeroNode temp = null;
//左递归
if (this.left != null){
temp = this.left.infixSearch(no);
}
//说明左子树找到了
if (temp != null){
return temp;
}
//根
if (this.no == no){
//System.out.println("找到了no="+no+"的节点:" + this);
return this;
}
//右递归
if (this.right != null){
temp = this.right.infixSearch(no);
}
return temp;
}
//后序查找
public HeroNode suffixSearch(int no){
HeroNode temp = null;
//左递归
if (this.left != null){
temp = this.left.suffixSearch(no);
}
//说明左子树找到了
if (temp != null){
return temp;
}
//右递归
if (this.right != null){
temp = this.right.suffixSearch(no);
}
//根
if (this.no == no){
//System.out.println("找到了no="+no+"的节点:" + this);
return this;
}
return temp;
}
//根据no删除指定节点
//说明:1、如果删除的节点是叶子节点,那么直接删除叶子节点
//说明:2、如果要删除的节点是父节点,则直接删除整棵子树
//说明:3、如果要删除的节点是根节点,则报错,返回信息:不能删除根节点
public boolean deleteByNO(int no,HeroNode root){
boolean flag = false;
//如果要删除根节点,直接将整棵树删除
if (root.no == no){
throw new RuntimeException("不能删除根节点");
}
if (this.left != null && this.left.no == no){
this.left = null;
return true;
}
if (this.right != null && this.right.no == no){
this.right = null;
return true;
}
//递归左子树
if (this.left != null){
flag = this.left.deleteByNO(no,root);
}
//递归右子树
if (this.right != null){
flag = this.right.deleteByNO(no,root);
}
return flag;
}
public HeroNode() {
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
}
调用节点对象中的方法完成二叉树的基本操作:
public class BinaryTree {
private HeroNode root;
public HeroNode getRoot() {
return root;
}
public void setRoot(HeroNode root) {
this.root = root;
}
//前序遍历
public void preOrder(){
if (this.root != null){
this.root.prefixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//中序遍历
public void inOrder(){
if (this.root != null){
this.root.infixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//后序遍历
public void sufOrder(){
if (this.root != null){
this.root.suffixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//根据no删除节点
public void dropByNO(int no){
boolean flag;
if (this.root != null){
flag = this.root.deleteByNO(no,this.root);
}else {
System.out.println("二叉树为空");
return;
}
if (flag){
System.out.println("删除成功");
}else {
System.out.println("没有找到要删除的节点");
}
}
//前序查找
public void preSearch(int no){
//接收返回值
HeroNode temp = null;
if (this.root != null){
temp = this.root.prefixSearch(no);
}else {
System.out.println("二叉树为空");
}
if (temp == null){
System.out.println("没有找到no="+no+"的节点");
}else {
System.out.println("找到了no="+no+"的节点:" + temp);
}
}
//中序查找
public void inSearch(int no){
HeroNode temp = null;
if (this.root != null){
temp = this.root.infixSearch(no);
}else {
System.out.println("二叉树为空");
}
if (temp == null){
System.out.println("没有找到no="+no+"的节点");
}else {
System.out.println("找到了no="+no+"的节点:" + temp);
}
}
//后序查找
public void sufSearch(int no){
HeroNode temp = null;
if (this.root != null){
temp = this.root.suffixSearch(no);
}else {
System.out.println("二叉树为空");
}
if (temp == null){
System.out.println("没有找到no="+no+"的节点");
}else {
System.out.println("找到了no="+no+"的节点:" + temp);
}
}
}
测试二叉树的操作:
public class BinaryTreeDemo {
public static void main(String[] args) {
//先创建二叉树
BinaryTree binaryTree = new BinaryTree();
//创建树的节点
HeroNode heroNode1 = new HeroNode(1,"宋江");
HeroNode heroNode2 = new HeroNode(2,"吴用");
HeroNode heroNode3 = new HeroNode(3,"卢俊义");
HeroNode heroNode4 = new HeroNode(4,"林冲");
HeroNode heroNode5 = new HeroNode(5,"武松");
//便于测试,先手动创建二叉树
binaryTree.setRoot(heroNode1);
binaryTree.getRoot().setLeft(heroNode2);
binaryTree.getRoot().setRight(heroNode3);
heroNode3.setRight(heroNode4);
heroNode3.setLeft(heroNode5);
System.out.println("前序遍历:"); // 1 2 3 5 4
binaryTree.preOrder();
System.out.println("中序遍历:"); // 2 1 5 3 4
binaryTree.inOrder();
System.out.println("后序遍历:"); // 2 5 4 3 1
binaryTree.sufOrder();
//前序法查找no为5的节点
System.out.println("前序查找:");
binaryTree.preSearch(2);
//中序法查找no为5的节点
System.out.println("中序查找:");
binaryTree.inSearch(3);
//后序法查找no为5的节点
System.out.println("后序查找:");
binaryTree.sufSearch(4);
//删除节点5
binaryTree.dropByNO(2);
System.out.println("删除节点2后前序遍历:"); // 1 2 3 5 4
binaryTree.preOrder();
//删除节点3
binaryTree.dropByNO(3);
System.out.println("删除节点3后前序遍历:"); // 1 2 3 5 4
binaryTree.preOrder();
}
}