學習地址: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);
}
}
🚀🚀🚀🚀🚀🚀