前言
Java实现平衡二叉搜索树的定义,代码是参考(copy)文章的代码定义,在原来的基础上添加了树的层次遍历,并且层次遍历可以打印出层序,增加了更多的测试用例,期待后面可以增加结点的删除功能。
代码
2.1节点的定义
/**
* 平衡二叉搜索树节点定义
*/
public class AVLNode {
/** 数据 **/
public int data;
/** 相对高度 **/
public int height;
/** 父节点 **/
public AVLNode parent;
/** 左子树 **/
public AVLNode left;
/** 右子树 **/
public AVLNode right;
public AVLNode(int data) {
this.data = data;
this.height = 1;
}
}
2.2 平衡二叉树的定义
/**
* 模仿AVLTree写出二叉树的平衡
*
* @author Caolele
* @since 12-19-2022 周一
*/
public class AVLTreeImitation {
AVLNode root;
public void insert(int data){
if(root == null){
root = new AVLNode(data);
}else {
root = insert(root, data);
}
}
AVLNode insert(AVLNode root,int data){
if(data <root.data){
if(root.left == null){
root.left = new AVLNode(data);
root.left.parent = root.left;
}else {
root.left = insert(root.left, data);
}
}else {
if(root.right == null)
{
root.right = new AVLNode(data);
root.right.parent = root.right;
}else {
root.right = insert(root.right, data);
}
}
//走到这一步一定是新插入了节点,所以需要当前节点的高度
root.height = calcHeight(root);
//开始进行旋转使之满足平衡搜索二叉树的定义
if(calcBF(root) == 2){ //若是LL型仅需右旋
if( -1 == calcBF(root.left)){ //判断是否需要左旋
root.left = leftRotate(root.left);
}
root = rightRotate(root);
}
if(calcBF(root) == -2){ //若是LL型仅需右旋
if( 1 == calcBF(root.right)){ //判断是否需要左旋
root.right = rightRotate(root.right);
}
root = leftRotate(root);
}
return root;
}
public AVLNode leftRotate(AVLNode root) {
AVLNode parent = root.parent;
AVLNode newNode = root.right;
AVLNode oldNode = root;
if (parent != null) {
if (parent.data > newNode.data) {
parent.left = newNode;
} else {
parent.right = newNode;
}
newNode.parent = parent;
}
AVLNode left = newNode.left;
newNode.left = oldNode.right;
oldNode.parent = newNode;
if (left != null) {
left.parent = oldNode;
}
oldNode.right = left; //当left为null时,让oldNode.right 赋值为null
//这里要先计算旧节点的高度才能在此基础上计算新节点的高度
oldNode.height = calcHeight(oldNode);
newNode.height = calcHeight(newNode);
return newNode;
}
/**
* 右旋
* @param root
* @return
*/
AVLNode rightRotate( AVLNode root) {
AVLNode parent = root.parent;
AVLNode newNode = root.left;
AVLNode oldNode = root;
if(parent!=null){
if(parent.data>newNode.data){
parent.left = newNode;
}else {
parent.right = newNode;
}
newNode.parent = parent;
}
AVLNode right = newNode.right;
newNode.right = oldNode;
oldNode.parent = newNode;
if(right != null){
right.parent = oldNode;
}
oldNode.left = right;//当right为null时,让oldNode.left 赋值为null
oldNode.height = calcHeight(oldNode);
newNode.height = calcHeight(newNode);
return newNode;
}
/**
* 计算结点的平衡因子
*
* @param root
* @return
*/
int calcBF(AVLNode root) {
if (root == null) {
return 0;
} else if (root.left == null) {
return -root.right.height;
} else if (root.right == null) {
return root.left.height;
} else if (root.left == null && root.right == null) {
return 0;
} else {
return root.left.height - root.right.height;
}
}
/**
* 计算Node的高度
*
* @param root
* @return
*/
int calcHeight(AVLNode root) {
if (root.left == null && root.right == null) {
return 1;
} else if (root.left == null) {
return root.right.height + 1;
} else if (root.right == null) {
return root.left.height + 1;
} else {
if (root.left.height >= root.right.height) {
return root.left.height + 1;
} else {
return root.right.height + 1;
}
}
}
public static void main(String[] args) {
AVLTree tree = new AVLTree();
//test1
// tree.insert(1);
// tree.insert(2);
// tree.insert(3);
//test2
// tree.insert(3);
// tree.insert(2);
// tree.insert(1);
//test3
// tree.insert(1);
// tree.insert(3);
// tree.insert(2);
//test4
// tree.insert(3);
// tree.insert(1);
// tree.insert(2);
//test5
tree.insert(10);
tree.insert(4);
tree.insert(14);
tree.insert(3);
tree.insert(6);
tree.insert(5);
levelTraverse(tree.root);
}
//层序遍历
private static void levelTraverse(AVLNode root) {
if (root == null) {
return;
}
List<AVLNode> list = new LinkedList<>();
list.add(root);
AVLNode nLast = root;
while (!list.isEmpty()) {
AVLNode pop = list.remove(0);
System.out.print(pop.data+"\t");
if (pop.left != null) {
list.add(pop.left);
}
if (pop.right != null) {
list.add(pop.right);
}
//此时第上层遍历完毕,并且下一层也完全装入到了队列
if(pop == nLast && !list.isEmpty()){
System.out.println();
nLast = list.get(list.size()-1);
}
}
}
}