数据结构Java08【二叉平衡树(AVL)-概述、单旋转、双旋转】
生活随笔
收集整理的這篇文章主要介紹了
数据结构Java08【二叉平衡树(AVL)-概述、单旋转、双旋转】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
學(xué)習(xí)地址:【數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)-java版】? ? ? ? ? ? ? ? ??🚀數(shù)據(jù)結(jié)構(gòu)--Java專欄🚀
- 筆記01【01-09】【概述、數(shù)組基本使用】【源碼、課件】
- 筆記02【10-18】【棧、隊(duì)列、單鏈表(增刪節(jié)點(diǎn))、循環(huán)鏈表、雙向循環(huán)鏈表、遞歸(斐波那契、漢諾塔)】
- 筆記03【19-27】【(時(shí)間、空間復(fù)雜度);八大排序(冒泡、快速、插入、希爾、選擇、歸并、基數(shù)、隊(duì)列基數(shù))】
- 筆記04【28-33】【樹結(jié)構(gòu)(二叉樹)概述、創(chuàng)建、遍歷、查找節(jié)點(diǎn)、刪除節(jié)點(diǎn)】
- 筆記05【34-39】【順序存儲(chǔ)二叉樹概述、二叉樹遍歷、堆排序、線索二叉樹實(shí)現(xiàn)及遍歷】
- 筆記06【40-48】【赫夫曼樹、概述、原理分析、代碼實(shí)現(xiàn)(數(shù)據(jù)壓縮、創(chuàng)建編碼表、解碼、壓縮文件、解壓文件)】
- 筆記07【49-54】【二叉排序樹(添加、查找、刪除節(jié)點(diǎn))】
- 筆記08【55-57】【二叉平衡樹(AVL)-概述、單旋轉(zhuǎn)、雙旋轉(zhuǎn)】
- 筆記09【58-60】【計(jì)算機(jī)中數(shù)據(jù)的存儲(chǔ)原理、2-3樹的插入原理、B樹和B+樹】
- 筆記10【61-63】【哈希表概述、散列函數(shù)的設(shè)計(jì)、散列沖突解決方案】
- 筆記11【64-67】【圖結(jié)構(gòu)概述、圖遍歷原理(BFS\DFS)、圖遍歷代碼實(shí)現(xiàn)】
目? ?錄
P55 4.28 平衡二叉樹概述
P56 4.29 構(gòu)建平衡二叉樹之單旋轉(zhuǎn)
P57 4.30 構(gòu)建平衡二叉樹之雙旋轉(zhuǎn)
代碼匯總
1、Node.java
2、BinarySortTree.java
3、TestBinarySortTree.java
P55 4.28 平衡二叉樹概述
AVL樹(平衡二叉樹):左子樹和右子樹的高度差的絕對(duì)值不超過(guò)1。(包括子樹!左子樹和右子樹,也是平衡二叉樹!)【查找效率比較高!】
【1、2、3、4、5、6、7、8】二叉排序樹-->查找不方便!
P56 4.29 構(gòu)建平衡二叉樹之單旋轉(zhuǎn)
將 二叉排序樹 轉(zhuǎn)換為 平衡樹,保證查找效率!
每加入一個(gè)節(jié)點(diǎn),就要檢查一次。-->是否進(jìn)行旋轉(zhuǎn)!
P57 4.30 構(gòu)建平衡二叉樹之雙旋轉(zhuǎn)
代碼匯總
1、Node.java
package demo12;public class Node {int value;Node left;Node right;public Node(int value) {this.value = value;}/*** 返回當(dāng)前節(jié)點(diǎn)的高度* * @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();}/*** 向子樹中添加節(jié)點(diǎn)* * @param node*/public void add(Node node) {if (node == null) {return;}// 判斷傳入的節(jié)點(diǎn)的值比當(dāng)前子樹的根節(jié)點(diǎn)的值大還是小// 添加的節(jié)點(diǎn)比當(dāng)前節(jié)點(diǎn)的值更小if (node.value < this.value) {// 如果左節(jié)點(diǎn)為空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);}}// 查詢是否平衡// 進(jìn)行右旋轉(zhuǎn)if (leftHeight() - rightHeight() >= 2) {// 雙旋轉(zhuǎn)if (left != null && left.leftHeight() < left.rightHeight()) {// 先左旋轉(zhuǎn)left.leftRotate();// 再右旋轉(zhuǎn)rightRotate();// 單旋轉(zhuǎn)} else {rightRotate();}}// 左旋轉(zhuǎn)if (leftHeight() - rightHeight() <= -2) {// 雙旋轉(zhuǎn)if (right != null && right.rightHeight() < right.leftHeight()) {right.rightRotate();leftRotate();// 單旋轉(zhuǎn)} else {leftRotate();}}}/*** 左旋轉(zhuǎn)*/private void leftRotate() {Node newLeft = new Node(value);newLeft.left = left;newLeft.right = right.left;value = right.value;right = right.right;left = newLeft;}/*** 右旋轉(zhuǎn)*/private void rightRotate() {// 創(chuàng)建一個(gè)新的節(jié)點(diǎn),值等于當(dāng)前節(jié)點(diǎn)的值Node newRight = new Node(value);// 把新節(jié)點(diǎn)的右子樹設(shè)置了當(dāng)前節(jié)點(diǎn)的右子樹newRight.right = right;// 把新節(jié)點(diǎn)的左子樹設(shè)置為當(dāng)前節(jié)點(diǎn)的左子樹的右子樹newRight.left = left.right;// 把當(dāng)前節(jié)點(diǎn)的值換為左子節(jié)點(diǎn)的值value = left.value;// 把當(dāng)前節(jié)點(diǎn)的左子樹設(shè)置了左子樹的左子樹left = left.left;// 把當(dāng)前節(jié)點(diǎn)的右子樹設(shè)置為新節(jié)點(diǎn)right = newRight;}/*** 中序遍歷* * @param node*/public void midShow(Node node) {if (node == null) {return;}midShow(node.left);System.out.println(node.value);midShow(node.right);}/*** 查找節(jié)點(diǎn)* * @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);}}/*** 搜索父節(jié)點(diǎn)* * @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;/*** 向二叉排序樹中添加節(jié)點(diǎn)* * @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);}}/*** 節(jié)點(diǎn)的查找* * @param value* @return*/public Node search(int value) {if (root == null) {return null;} else {return root.search(value);}}/*** 刪除節(jié)點(diǎn)* * @param value*/public void delete(int value) {if (root == null) {return;} else {// 找到這個(gè)節(jié)點(diǎn)Node target = search(value);// 如果沒(méi)有這個(gè)節(jié)點(diǎn)if (target == null) {return;}// 找到他的父節(jié)點(diǎn)Node parent = searchParent(value);// 要?jiǎng)h除的節(jié)點(diǎn)是葉子節(jié)點(diǎn)if (target.left == null && target.right == null) {// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子節(jié)點(diǎn)if (parent.left.value == value) {parent.left = null;// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的右子節(jié)點(diǎn)} else {parent.right = null;}// 要?jiǎng)h除的節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)的情況} else if (target.left != null && target.right != null) {// 刪除右子樹中值最小的節(jié)點(diǎn),取獲取到該節(jié)點(diǎn)的值int min = deleteMin(target.right);// 替換目標(biāo)節(jié)點(diǎn)中的值target.value = min;// 要?jiǎng)h除的節(jié)點(diǎn)有一個(gè)左子節(jié)點(diǎn)或右子節(jié)點(diǎn)} else {// 有左子節(jié)點(diǎn)if (target.left != null) {// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子節(jié)點(diǎn)if (parent.left.value == value) {parent.left = target.left;// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的右子節(jié)點(diǎn)} else {parent.right = target.left;}// 有右子節(jié)點(diǎn)} else {// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的左子節(jié)點(diǎn)if (parent.left.value == value) {parent.left = target.right;// 要?jiǎng)h除的節(jié)點(diǎn)是父節(jié)點(diǎn)的右子節(jié)點(diǎn)} else {parent.right = target.right;}}}}}/*** 刪除一顆樹中最小的節(jié)點(diǎn)* * @param right* @return*/private int deleteMin(Node node) {Node target = node;// 遞歸向左找while (target.left != null) {target = target.left;}// 刪除最小的這個(gè)節(jié)點(diǎn)delete(target.value);return target.value;}/*** 搜索父節(jié)點(diǎn)* * @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 };// 創(chuàng)建一顆二叉排序樹BinarySortTree bst = new BinarySortTree();// 循環(huán)添加for (int i : arr) {bst.add(new Node(i));}// 查看高度System.out.println(bst.root.height());System.out.println(bst.root.value);}}🚀🚀🚀🚀🚀🚀
總結(jié)
以上是生活随笔為你收集整理的数据结构Java08【二叉平衡树(AVL)-概述、单旋转、双旋转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JavaScript基础01【简介、js
- 下一篇: java美元兑换,(Java实现) 美元