学习地址:https://www.bilibili.com/video/BV1Zt411o7Rn【数据结构与算法基础-java版】
🚀数据结构--Java专栏:https://blog.csdn.net/weixin_44949135/category_10103369.html🚀
笔记01【01-09】https://blog.csdn.net/weixin_44949135/article/details/106742935【概述、数组基本使用】【源码、课件】
笔记02【10-18】https://blog.csdn.net/weixin_44949135/article/details/106746038【栈、队列、单链表、链表、递归】
笔记03【19-27】https://blog.csdn.net/weixin_44949135/article/details/106784224【八大排序算法】
笔记04【28-33】https://blog.csdn.net/weixin_44949135/article/details/106823785【树结构概述、二叉树】
笔记05【34-39】https://blog.csdn.net/weixin_44949135/article/details/106832176【顺序存储二叉树、堆排、线索二叉树】
笔记06【40-48】https://blog.csdn.net/weixin_44949135/article/details/106843814【赫夫曼树、解码、压缩&解压文件】
笔记07【49-54】https://blog.csdn.net/weixin_44949135/article/details/106886659【二叉排序树】
笔记08【55-57】https://blog.csdn.net/weixin_44949135/article/details/106896570【平衡二叉树(AVL)】
笔记09【58-60】https://blog.csdn.net/weixin_44949135/article/details/106852286【计算机数据存储原理、2-3树、B树】
笔记10【61-63】https://blog.csdn.net/weixin_44949135/article/details/106936504【哈希表、散列函数设计、解决冲突】
笔记11【64-67】https://blog.csdn.net/weixin_44949135/article/details/106939350【图概述、图遍历(DFS、BFS)】
目 录
P55 4.28 平衡二叉树概述
AVL树(平衡二叉树):左子树和右子树的高度差的绝对值不超过1。(包括子树!左子树和右子树,也是平衡二叉树!)【查找效率比较高!】
【1、2、3、4、5、6、7、8】二叉排序树-->查找不方便!
P56 4.29 构建平衡二叉树之单旋转
将 二叉排序树 转换为 平衡树,保证查找效率!
每加入一个节点,就要检查一次。-->是否进行旋转!
P57 4.30 构建平衡二叉树之双旋转
代码汇总
1、Node.java
package demo12;
public class Node {
int value;
Node left;
Node right;
public Node(int value) {
this.value = value;
}
/**
* 返回当前节点的高度
*
* @return
*/
public int height() {
return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1;
}
/**
* 获取左子树的高度
*
* @return
*/
public int leftHeight() {
if (left == null) {
return 0;
}
return left.height();
}
/**
* 获取右子树的高度
*
* @return
*/
public int rightHeight() {
if (right == null) {
return 0;
}
return right.height();
}
/**
* 向子树中添加节点
*
* @param node
*/
public void add(Node node) {
if (node == null) {
return;
}
// 判断传入的节点的值比当前子树的根节点的值大还是小
// 添加的节点比当前节点的值更小
if (node.value < this.value) {
// 如果左节点为空
if (this.left == null) {
this.left = node;
// 如果不为空
} else {
this.left.add(node);
}
} else {
if (this.right == null) {
this.right = node;
} else {
this.right.add(node);
}
}
// 查询是否平衡
// 进行右旋转
if (leftHeight() - rightHeight() >= 2) {
// 双旋转
if (left != null && left.leftHeight() < left.rightHeight()) {
// 先左旋转
left.leftRotate();
// 再右旋转
rightRotate();
// 单旋转
} else {
rightRotate();
}
}
// 左旋转
if (leftHeight() - rightHeight() <= -2) {
// 双旋转
if (right != null && right.rightHeight() < right.leftHeight()) {
right.rightRotate();
leftRotate();
// 单旋转
} else {
leftRotate();
}
}
}
/**
* 左旋转
*/
private void leftRotate() {
Node newLeft = new Node(value);
newLeft.left = left;
newLeft.right = right.left;
value = right.value;
right = right.right;
left = newLeft;
}
/**
* 右旋转
*/
private void rightRotate() {
// 创建一个新的节点,值等于当前节点的值
Node newRight = new Node(value);
// 把新节点的右子树设置了当前节点的右子树
newRight.right = right;
// 把新节点的左子树设置为当前节点的左子树的右子树
newRight.left = left.right;
// 把当前节点的值换为左子节点的值
value = left.value;
// 把当前节点的左子树设置了左子树的左子树
left = left.left;
// 把当前节点的右子树设置为新节点
right = newRight;
}
/**
* 中序遍历
*
* @param node
*/
public void midShow(Node node) {
if (node == null) {
return;
}
midShow(node.left);
System.out.println(node.value);
midShow(node.right);
}
/**
* 查找节点
*
* @param value2
*/
public Node search(int value) {
if (this.value == value) {
return this;
} else if (value < this.value) {
if (left == null) {
return null;
}
return left.search(value);
} else {
if (right == null) {
return null;
}
return right.search(value);
}
}
/**
* 搜索父节点
*
* @param value
* @return
*/
public Node searchParent(int value) {
if ((this.left != null && this.left.value == value) || (this.right != null && this.right.value == value)) {
return this;
} else {
if (this.value > value && this.left != null) {
return this.left.searchParent(value);
} else if (this.value < value && this.right != null) {
return this.right.searchParent(value);
}
return null;
}
}
}
2、BinarySortTree.java
package demo12;
public class BinarySortTree {
Node root;
/**
* 向二叉排序树中添加节点
*
* @param node
*/
public void add(Node node) {
// 如果是一颗空树
if (root == null) {
root = node;
} else {
root.add(node);
}
}
/**
* 中序遍历二叉排序树,从小到大的顺序
*/
public void midShow() {
if (root != null) {
root.midShow(root);
}
}
/**
* 节点的查找
*
* @param value
* @return
*/
public Node search(int value) {
if (root == null) {
return null;
} else {
return root.search(value);
}
}
/**
* 删除节点
*
* @param value
*/
public void delete(int value) {
if (root == null) {
return;
} else {
// 找到这个节点
Node target = search(value);
// 如果没有这个节点
if (target == null) {
return;
}
// 找到他的父节点
Node parent = searchParent(value);
// 要删除的节点是叶子节点
if (target.left == null && target.right == null) {
// 要删除的节点是父节点的左子节点
if (parent.left.value == value) {
parent.left = null;
// 要删除的节点是父节点的右子节点
} else {
parent.right = null;
}
// 要删除的节点有两个子节点的情况
} else if (target.left != null && target.right != null) {
// 删除右子树中值最小的节点,取获取到该节点的值
int min = deleteMin(target.right);
// 替换目标节点中的值
target.value = min;
// 要删除的节点有一个左子节点或右子节点
} else {
// 有左子节点
if (target.left != null) {
// 要删除的节点是父节点的左子节点
if (parent.left.value == value) {
parent.left = target.left;
// 要删除的节点是父节点的右子节点
} else {
parent.right = target.left;
}
// 有右子节点
} else {
// 要删除的节点是父节点的左子节点
if (parent.left.value == value) {
parent.left = target.right;
// 要删除的节点是父节点的右子节点
} else {
parent.right = target.right;
}
}
}
}
}
/**
* 删除一颗树中最小的节点
*
* @param right
* @return
*/
private int deleteMin(Node node) {
Node target = node;
// 递归向左找
while (target.left != null) {
target = target.left;
}
// 删除最小的这个节点
delete(target.value);
return target.value;
}
/**
* 搜索父节点
*
* @param value
* @return
*/
public Node searchParent(int value) {
if (root == null) {
return null;
} else {
return root.searchParent(value);
}
}
}
3、TestBinarySortTree.java
package demo12;
public class TestBinarySortTree {
public static void main(String[] args) {
// int[] arr = new int[] {8,9,6,7,5,4};
int[] arr = new int[] { 8, 9, 5, 4, 6, 7 };
// 创建一颗二叉排序树
BinarySortTree bst = new BinarySortTree();
// 循环添加
for (int i : arr) {
bst.add(new Node(i));
}
// 查看高度
System.out.println(bst.root.height());
System.out.println(bst.root.value);
}
}
🚀🚀🚀🚀🚀🚀