/**
* 创建树的节点 -----链式
* @author Mona
*
*/
public class TreeNode {
//节点的权
int value;
//左儿子
TreeNode leftNode;
//右儿子
TreeNode rightNode;
public TreeNode(int value) {
this.value = value;
}
//设置左儿子
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
//设置右儿子
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
//前序遍历
public void frontShow() {
//先打印自己的值[先遍历当前结点的内容]
System.out.println(value);
//左边node
if(leftNode != null) {
leftNode.frontShow();//递归操作可能没有,需在前面添加判断
}
//右结点
if(rightNode != null) {
rightNode.frontShow(); //递归 //前序遍历输出:1 2 4 5 3 6 7
}
}
//中序遍历
public void midShow() {
//左结点
if(leftNode != null) {
leftNode.midShow();
}
//当前结点
System.out.println(value);
//右结点
if(rightNode != null) {
rightNode.midShow();
}
}
//后序遍历
public void afterShow() {
// 左结点
if (leftNode != null) {
leftNode.afterShow();
}
// 右结点
if (rightNode != null) {
rightNode.afterShow();
}
// 当前结点
System.out.println(value);
}
//前序查找 ------------------->二叉树中的结点查找
public TreeNode frontSearch(int i) {
TreeNode target = null;
//对比当前结点的值
if(this.value == i) {
return this;
//当前结点的值不是要查找的结点
}else {
//查找左儿子
if(leftNode != null) {
//有可能查得到,也可能查不到,查不到的话,target还是一个null
target = leftNode.frontSearch(i);
}
//如果不为空,说明在左儿子中已经找到
if(target != null) {
return target;
}
//查找右孩子
if(rightNode != null) {
target = rightNode.frontSearch(i);
}
}
return target;
}
//中序查找
public TreeNode middleSearch(int i) {
TreeNode target = null;
if(leftNode != null) {
target = leftNode.middleSearch(i);
}else {
if(this.value == i) {
return this;
}
if(rightNode != null) {
target = rightNode.middleSearch(i);
}
}
return target;
}
//删除二叉树的子树
public void delete(int i) {
TreeNode parent = this;
//判断左儿子
if(parent.leftNode != null && parent.leftNode.value == i) { //注意判断是否为空
parent.leftNode = null;
return ;
}
if(parent.rightNode != null && parent.rightNode.value == i) {
parent.rightNode = null;
return;
}
//递归检查并删除左儿子
parent = leftNode;
if(parent != null) {
parent.delete(i);
}
parent = rightNode;
if(parent != null) {
parent.delete(i);
}
}
}
/**
* 设置根
* @author Mona
*
*/
public class BinaryTree {
TreeNode root;
//设置根节点
public void setRoot(TreeNode root) {
this.root = root;
}
//获取根节点
public TreeNode getRoot() {
return root;
}
public void frontShow() {
if(root != null) { //删除根结点时使用到的,如果根结点没有了,则不可以进行调用,空指针
//调root
root.frontShow();
}
}
public void midShow() {
if(root != null) {
root.midShow();
}
}
public void afterShow() {
if(root != null) {
root.afterShow();
}
}
public TreeNode frontSearch(int i) {
return root.frontSearch(i);
}
public TreeNode middleSearch(int i) {
return root.middleSearch(i);
}
public void delete(int i) {
if(root.value == i) {
root = null;
}else{
root.delete(i);
}
}
}
/**
* 主方法----测试
* @author Mona
*
*/
public class TestBinaryTree {
public static void main(String[] args) {
//创建一棵树
BinaryTree binTree = new BinaryTree();
//创建一个根结点
TreeNode root = new TreeNode(1);
binTree.setRoot(root);//把根节点赋给树
TreeNode rootL = new TreeNode(2);//创建一个左节点
root.setLeftNode(rootL);//把新创建的节点设置为根节点的子结点
TreeNode rootR = new TreeNode(3);///创建一个右结点
root.setRightNode(rootR);//把新创建的结点设置为根结点的子结点
rootL.setLeftNode(new TreeNode(4));//为第二层的左结点创建两个子结点
rootL.setRightNode(new TreeNode(5));
rootR.setLeftNode(new TreeNode(6));//为第二层的右结点创建两个子结点
rootR.setRightNode(new TreeNode(7));
//前序遍历
binTree.frontShow();
System.out.println("---------------------");
//中序遍历
binTree.midShow();
System.out.println("=====================");
//后序遍历
binTree.afterShow();
//前序查找
TreeNode result = binTree.frontSearch(5);
System.out.println(result);
TreeNode resultm = binTree.middleSearch(4);
System.out.println(resultm);
System.out.println("==========================");
//删除根结点时,相应的它下面的子左右结点都被删除了
//删除二叉树中的一个子树
binTree.delete(2);
binTree.frontShow();
}
}
我认为无需展示链表代码,因为题目是关于平衡二叉树的,与链表没有太大关系。关于如何平衡二叉树,常用的算法有AVL树和红黑树,其中AVL树是一种严格平衡的二叉树,它的左右子树的高度差的绝对值不超过1,每次插入或删除节点后都需要对整棵树进行旋转,以保证平衡。而红黑树则是一种近似平衡的二叉树,它也是通过旋转来保持平衡,但它对平衡的定义要宽松一些,左右子树高度差可以达到两倍。相比AVL树,红黑树的简单和高效性使它在现实中更为常用。
在编写二叉树时,需要注意以下几点:
以上是我对如何平衡二叉树的解释和二叉树编写的一些注意点,如果有不足之处还请指正。