
- 資料結構與演算法
- DSA - 首頁
- DSA - 概述
- DSA - 環境搭建
- DSA - 演算法基礎
- DSA - 漸進分析
- 資料結構
- DSA - 資料結構基礎
- DSA - 資料結構和型別
- DSA - 陣列資料結構
- 連結串列
- DSA - 連結串列資料結構
- DSA - 雙向連結串列資料結構
- DSA - 迴圈連結串列資料結構
- 棧與佇列
- DSA - 棧資料結構
- DSA - 表示式解析
- DSA - 佇列資料結構
- 搜尋演算法
- DSA - 搜尋演算法
- DSA - 線性搜尋演算法
- DSA - 二分搜尋演算法
- DSA - 插值搜尋
- DSA - 跳躍搜尋演算法
- DSA - 指數搜尋
- DSA - 斐波那契搜尋
- DSA - 子列表搜尋
- DSA - 雜湊表
- 排序演算法
- DSA - 排序演算法
- DSA - 氣泡排序演算法
- DSA - 插入排序演算法
- DSA - 選擇排序演算法
- DSA - 歸併排序演算法
- DSA - 希爾排序演算法
- DSA - 堆排序
- DSA - 桶排序演算法
- DSA - 計數排序演算法
- DSA - 基數排序演算法
- DSA - 快速排序演算法
- 圖資料結構
- DSA - 圖資料結構
- DSA - 深度優先遍歷
- DSA - 廣度優先遍歷
- DSA - 生成樹
- 樹資料結構
- DSA - 樹資料結構
- DSA - 樹的遍歷
- DSA - 二叉搜尋樹
- DSA - AVL樹
- DSA - 紅黑樹
- DSA - B樹
- DSA - B+樹
- DSA - 伸展樹
- DSA - 字典樹
- DSA - 堆資料結構
- 遞迴
- DSA - 遞迴演算法
- DSA - 使用遞迴實現漢諾塔
- DSA - 使用遞迴實現斐波那契數列
- 分治法
- DSA - 分治法
- DSA - 最大最小問題
- DSA - Strassen矩陣乘法
- DSA - Karatsuba演算法
- 貪心演算法
- DSA - 貪心演算法
- DSA - 旅行商問題(貪心法)
- DSA - Prim最小生成樹
- DSA - Kruskal最小生成樹
- DSA - Dijkstra最短路徑演算法
- DSA - 地圖著色演算法
- DSA - 分數揹包問題
- DSA - 帶截止日期的作業排序
- DSA - 最優合併模式演算法
- 動態規劃
- DSA - 動態規劃
- DSA - 矩陣鏈乘法
- DSA - Floyd Warshall演算法
- DSA - 0-1揹包問題
- DSA - 最長公共子序列演算法
- DSA - 旅行商問題(動態規劃法)
- 近似演算法
- DSA - 近似演算法
- DSA - 頂點覆蓋演算法
- DSA - 集合覆蓋問題
- DSA - 旅行商問題(近似演算法)
- 隨機演算法
- DSA - 隨機演算法
- DSA - 隨機快速排序演算法
- DSA - Karger最小割演算法
- DSA - Fisher-Yates洗牌演算法
- DSA有用資源
- DSA - 問答
- DSA - 快速指南
- DSA - 有用資源
- DSA - 討論
AVL樹
AVL樹是第一個發明的自平衡二叉搜尋樹。AVL樹的名字來源於其發明者的名字——Adelson-Velsky和Landis。
在AVL樹中,左右子樹高度之差,稱為**平衡因子**,必須最多為1。一旦差值超過1,樹就會自動執行平衡演算法,直到差值再次變為1。
BALANCE FACTOR = HEIGHT(LEFT SUBTREE) − HEIGHT(RIGHT SUBTREE)
AVL樹的平衡演算法中通常有四種旋轉情況:LL、RR、LR、RL。
LL旋轉
當節點插入到右子樹導致樹不平衡時,執行LL旋轉。這是一種單左旋轉,使樹再次平衡:

圖:LL旋轉
發生不平衡的節點成為左子節點,新新增的節點成為右子節點,中間節點作為父節點。
RR旋轉
當節點插入到左子樹導致樹不平衡時,執行RR旋轉。這是一種單右旋轉,使樹再次平衡:

圖:RR旋轉
發生不平衡的節點成為右子節點,新新增的節點成為左子節點,中間節點作為父節點。
LR旋轉
LR旋轉是前面單旋轉的擴充套件版本,也稱為雙旋轉。當節點插入到左子樹的右子樹時執行。LR旋轉是左旋轉後接右旋轉的組合。執行此操作需要遵循多個步驟。
以“A”作為根節點,“B”作為“A”的左子節點,“C”作為“B”的右子節點為例。
由於不平衡發生在A處,因此對A的子節點B和C應用左旋轉。
旋轉後,C節點成為A的左子節點,B成為C的左子節點。
不平衡仍然存在,因此在根節點A和左子節點C處應用右旋轉。
最終右旋轉後,C成為根節點,A成為右子節點,B是左子節點。

圖:LR旋轉
RL旋轉
RL旋轉也是前面單旋轉的擴充套件版本,因此稱為雙旋轉,如果節點插入到右子樹的左子樹中則執行。RL旋轉是右旋轉後接左旋轉的組合。執行此操作需要遵循多個步驟。
以“A”作為根節點,“B”作為“A”的右子節點,“C”作為“B”的左子節點為例。
由於不平衡發生在A處,因此對A的子節點B和C應用右旋轉。
旋轉後,C節點成為A的右子節點,B成為C的右子節點。
不平衡仍然存在,因此在根節點A和右子節點C處應用左旋轉。
最終左旋轉後,C成為根節點,A成為左子節點,B是右子節點。

圖:RL旋轉
AVL樹的基本操作
在AVL樹結構上執行的基本操作包括在二叉搜尋樹上執行的所有操作,因為AVL樹的核心實際上只是一個保持其所有屬性的二叉搜尋樹。因此,在AVL樹上執行的基本操作是:**插入**和**刪除**。
插入操作
透過遵循二叉搜尋樹的插入屬性將資料插入到AVL樹中,即左子樹必須包含小於根值的元素,右子樹必須包含所有大於的元素。
但是,在AVL樹中,在插入每個元素後,會檢查樹的平衡因子;如果它不超過1,則樹保持不變。但是,如果平衡因子超過1,則應用平衡演算法重新調整樹,使平衡因子再次小於或等於1。
演算法執行AVL樹的插入操作涉及以下步驟:
Step 1 − Create a node Step 2 − Check if the tree is empty Step 3 − If the tree is empty, the new node created will become the root node of the AVL Tree. Step 4 − If the tree is not empty, we perform the Binary Search Tree insertion operation and check the balancing factor of the node in the tree. Step 5 − Suppose the balancing factor exceeds ±1, we apply suitable rotations on the said node and resume the insertion from Step 4.
讓我們透過構建一個包含1到7個整數的示例AVL樹來理解插入操作。
從第一個元素1開始,我們建立一個節點並測量平衡,即0。

由於二叉搜尋屬性和平衡因子都滿足,因此我們將另一個元素插入到樹中。

計算兩個節點的平衡因子,發現為-1(左子樹的高度為0,右子樹的高度為1)。由於它不超過1,因此我們將另一個元素新增到樹中。

現在,新增第三個元素後,平衡因子超過1變為2。因此,應用旋轉。在這種情況下,應用RR旋轉,因為不平衡發生在兩個右節點上。

樹重新排列為:

類似地,使用這些旋轉插入和重新排列後續元素。重新排列後,我們得到如下樹:

以下是此操作在各種程式語言中的實現:
#include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node *leftChild; struct Node *rightChild; int height; }; int max(int a, int b); int height(struct Node *N){ if (N == NULL) return 0; return N->height; } int max(int a, int b){ return (a > b) ? a : b; } struct Node *newNode(int data){ struct Node *node = (struct Node *) malloc(sizeof(struct Node)); node->data = data; node->leftChild = NULL; node->rightChild = NULL; node->height = 1; return (node); } struct Node *rightRotate(struct Node *y){ struct Node *x = y->leftChild; struct Node *T2 = x->rightChild; x->rightChild = y; y->leftChild = T2; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; return x; } struct Node *leftRotate(struct Node *x){ struct Node *y = x->rightChild; struct Node *T2 = y->leftChild; y->leftChild = x; x->rightChild = T2; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; return y; } int getBalance(struct Node *N){ if (N == NULL) return 0; return height(N->leftChild) - height(N->rightChild); } struct Node *insertNode(struct Node *node, int data){ if (node == NULL) return (newNode(data)); if (data < node->data) node->leftChild = insertNode(node->leftChild, data); else if (data > node->data) node->rightChild = insertNode(node->rightChild, data); else return node; node->height = 1 + max(height(node->leftChild), height(node->rightChild)); int balance = getBalance(node); if (balance > 1 && data < node->leftChild->data) return rightRotate(node); if (balance < -1 && data > node->rightChild->data) return leftRotate(node); if (balance > 1 && data > node->leftChild->data) { node->leftChild = leftRotate(node->leftChild); return rightRotate(node); } if (balance < -1 && data < node->rightChild->data) { node->rightChild = rightRotate(node->rightChild); return leftRotate(node); } return node; } struct Node *minValueNode(struct Node *node){ struct Node *current = node; while (current->leftChild != NULL) current = current->leftChild; return current; } void printTree(struct Node *root){ if (root == NULL) return; if (root != NULL) { printTree(root->leftChild); printf("%d ", root->data); printTree(root->rightChild); } } int main(){ struct Node *root = NULL; root = insertNode(root, 22); root = insertNode(root, 14); root = insertNode(root, 72); root = insertNode(root, 44); root = insertNode(root, 25); root = insertNode(root, 63); root = insertNode(root, 98); printf("AVL Tree: "); printTree(root); return 0; }輸出
AVL Tree: 14 22 25 44 63 72 98
#include <iostream> struct Node { int data; struct Node *leftChild; struct Node *rightChild; int height; }; int max(int a, int b); int height(struct Node *N){ if (N == NULL) return 0; return N->height; } int max(int a, int b){ return (a > b) ? a : b; } struct Node *newNode(int data){ struct Node *node = (struct Node *) malloc(sizeof(struct Node)); node->data = data; node->leftChild = NULL; node->rightChild = NULL; node->height = 1; return (node); } struct Node *rightRotate(struct Node *y){ struct Node *x = y->leftChild; struct Node *T2 = x->rightChild; x->rightChild = y; y->leftChild = T2; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; return x; } struct Node *leftRotate(struct Node *x){ struct Node *y = x->rightChild; struct Node *T2 = y->leftChild; y->leftChild = x; x->rightChild = T2; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; return y; } int getBalance(struct Node *N){ if (N == NULL) return 0; return height(N->leftChild) - height(N->rightChild); } struct Node *insertNode(struct Node *node, int data){ if (node == NULL) return (newNode(data)); if (data < node->data) node->leftChild = insertNode(node->leftChild, data); else if (data > node->data) node->rightChild = insertNode(node->rightChild, data); else return node; node->height = 1 + max(height(node->leftChild), height(node->rightChild)); int balance = getBalance(node); if (balance > 1 && data < node->leftChild->data) return rightRotate(node); if (balance < -1 && data > node->rightChild->data) return leftRotate(node); if (balance > 1 && data > node->leftChild->data) { node->leftChild = leftRotate(node->leftChild); return rightRotate(node); } if (balance < -1 && data < node->rightChild->data) { node->rightChild = rightRotate(node->rightChild); return leftRotate(node); } return node; } struct Node *minValueNode(struct Node *node){ struct Node *current = node; while (current->leftChild != NULL) current = current->leftChild; return current; } void printTree(struct Node *root){ if (root == NULL) return; if (root != NULL) { printTree(root->leftChild); printf("%d ", root->data); printTree(root->leftChild); } } int main(){ struct Node *root = NULL; root = insertNode(root, 22); root = insertNode(root, 14); root = insertNode(root, 72); root = insertNode(root, 44); root = insertNode(root, 25); root = insertNode(root, 63); root = insertNode(root, 98); printf("AVL Tree: "); printTree(root); return 0; }輸出
AVL Tree: 14 22 14 44 14 22 14
import java.util.*; import java.io.*; class Node { int key, height; Node left, right; Node (int d) { key = d; height = 1; } } public class AVLTree { Node root; int height (Node N) { if (N == null) return 0; return N.height; } int max (int a, int b) { return (a > b) ? a : b; } Node rightRotate (Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; y.height = max (height (y.left), height (y.right)) + 1; x.height = max (height (x.left), height (x.right)) + 1; return x; } Node leftRotate (Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; x.height = max (height (x.left), height (x.right)) + 1; y.height = max (height (y.left), height (y.right)) + 1; return y; } int getBalance (Node N) { if (N == null) return 0; return height (N.left) - height (N.right); } Node insert (Node node, int key) { if (node == null) return (new Node (key)); if (key < node.key) node.left = insert (node.left, key); else if (key > node.key) node.right = insert (node.right, key); else return node; node.height = 1 + max (height (node.left), height (node.right)); int balance = getBalance (node); if (balance > 1 && key < node.left.key) return rightRotate (node); if (balance < -1 && key > node.right.key) return leftRotate (node); if (balance > 1 && key > node.left.key) { node.left = leftRotate (node.left); return rightRotate (node); } if (balance < -1 && key < node.right.key) { node.right = rightRotate (node.right); return leftRotate (node); } return node; } void printTree(Node root){ if (root == null) return; if (root != null) { printTree(root.left); System.out.print(root.key + " "); printTree(root.left); } } public static void main(String args[]) { AVLTree tree = new AVLTree(); tree.root = tree.insert(tree.root, 10); tree.root = tree.insert(tree.root, 11); tree.root = tree.insert(tree.root, 12); tree.root = tree.insert(tree.root, 13); tree.root = tree.insert(tree.root, 14); tree.root = tree.insert(tree.root, 15); System.out.println("AVL Tree: "); tree.printTree(tree.root); } }輸出
AVL Tree: 10 11 10 13 10 11 10
class Node(object): def __init__(self, data): self.data = data self.left = None self.right = None self.height = 1 class AVLTree(object): def insert(self, root, key): if not root: return Node(key) elif key < root.data: root.left = self.insert(root.left, key) else: root.right = self.insert(root.right, key) root.h = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) b = self.getBalance(root) if b > 1 and key < root.left.data: return self.rightRotate(root) if b < -1 and key > root.right.data: return self.leftRotate(root) if b > 1 and key > root.left.data: root.left = self.lefttRotate(root.left) return self.rightRotate(root) if b < -1 and key < root.right.data: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def leftRotate(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def rightRotate(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def getHeight(self, root): if not root: return 0 return root.height def getBalance(self, root): if not root: return 0 return self.getHeight(root.left) - self.getHeight(root.right) def Inorder(self, root): if root.left: self.Inorder(root.left) print(root.data) if root.right: self.Inorder(root.right) Tree = AVLTree() root = None root = Tree.insert(root, 10) root = Tree.insert(root, 13) root = Tree.insert(root, 11) root = Tree.insert(root, 14) root = Tree.insert(root, 12) root = Tree.insert(root, 15) # Inorder Traversal print("Inorder traversal of the AVL tree is") Tree.Inorder(root)輸出
Inorder traversal of the AVL tree is 10 11 12 13 14 15
刪除操作
AVL樹中的刪除發生在三種不同的場景中:
**場景1(刪除葉子節點)** - 如果要刪除的節點是葉子節點,則無需替換即可刪除,因為它不會干擾二叉搜尋樹屬性。但是,平衡因子可能會受到干擾,因此應用旋轉來恢復它。
**場景2(刪除只有一個子節點的節點)** - 如果要刪除的節點只有一個子節點,則用其子節點中的值替換該節點中的值。然後刪除子節點。如果平衡因子受到干擾,則應用旋轉。
**場景3(刪除有兩個子節點的節點)** - 如果要刪除的節點有兩個子節點,則找到該節點的中序後繼並將其值替換為中序後繼值。然後嘗試刪除中序後繼節點。如果刪除後平衡因子超過1,則應用平衡演算法。
使用上面給出的相同樹,讓我們在三種場景中執行刪除:

從上面的樹中刪除元素7:
由於元素7是葉子節點,因此我們通常刪除該元素而不干擾樹中的任何其他節點

從獲得的輸出樹中刪除元素6:
但是,元素6不是葉子節點,並且有一個子節點附加到它。在這種情況下,我們用其子節點:節點5替換節點6。

樹的平衡因子變為 1,並且由於它不超過 1,因此樹保持不變。如果我們進一步刪除元素 5,則需要應用左旋轉;由於不平衡發生在 1-2-4 和 3-2-4 處,因此可能是 LL 或 LR 旋轉。

刪除元素 5 後,平衡因子被擾亂,因此我們應用 LL 旋轉(這裡也可以應用 LR 旋轉)。

在路徑 1-2-4 上應用 LL 旋轉後,節點 3 保持不變,因為它應該成為節點 2 的右孩子(現在被節點 4 佔據)。因此,該節點被新增到節點 2 的右子樹中,並作為節點 4 的左孩子。

從剩餘樹中刪除元素 2 -
如場景 3 中所述,此節點有兩個子節點。因此,我們找到它的中序後繼節點(例如,3),該節點是葉子節點,並用中序後繼節點的值替換它的值。

樹的平衡因子仍然為 1,因此我們保持樹不變,不執行任何旋轉。
示例以下是此操作在各種程式語言中的實現:
#include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node *leftChild; struct Node *rightChild; int height; }; int max(int a, int b); int height(struct Node *N){ if (N == NULL) return 0; return N->height; } int max(int a, int b){ return (a > b) ? a : b; } struct Node *newNode(int data){ struct Node *node = (struct Node *) malloc(sizeof(struct Node)); node->data = data; node->leftChild = NULL; node->rightChild = NULL; node->height = 1; return (node); } struct Node *rightRotate(struct Node *y){ struct Node *x = y->leftChild; struct Node *T2 = x->rightChild; x->rightChild = y; y->leftChild = T2; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; return x; } struct Node *leftRotate(struct Node *x){ struct Node *y = x->rightChild; struct Node *T2 = y->leftChild; y->leftChild = x; x->rightChild = T2; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; return y; } int getBalance(struct Node *N){ if (N == NULL) return 0; return height(N->leftChild) - height(N->rightChild); } struct Node *insertNode(struct Node *node, int data){ if (node == NULL) return (newNode(data)); if (data < node->data) node->leftChild = insertNode(node->leftChild, data); else if (data > node->data) node->rightChild = insertNode(node->rightChild, data); else return node; node->height = 1 + max(height(node->leftChild), height(node->rightChild)); int balance = getBalance(node); if (balance > 1 && data < node->leftChild->data) return rightRotate(node); if (balance < -1 && data > node->rightChild->data) return leftRotate(node); if (balance > 1 && data > node->leftChild->data) { node->leftChild = leftRotate(node->leftChild); return rightRotate(node); } if (balance < -1 && data < node->rightChild->data) { node->rightChild = rightRotate(node->rightChild); return leftRotate(node); } return node; } struct Node *minValueNode(struct Node *node){ struct Node *current = node; while (current->leftChild != NULL) current = current->leftChild; return current; } struct Node *deleteNode(struct Node *root, int data){ if (root == NULL) return root; if (data < root->data) root->leftChild = deleteNode(root->leftChild, data); else if (data > root->data) root->rightChild = deleteNode(root->rightChild, data); else { if ((root->leftChild == NULL) || (root->rightChild == NULL)) { struct Node *temp = root->leftChild ? root->leftChild : root->rightChild; if (temp == NULL) { temp = root; root = NULL; } else *root = *temp; free(temp); } else { struct Node *temp = minValueNode(root->rightChild); root->data = temp->data; root->rightChild = deleteNode(root->rightChild, temp->data); } } if (root == NULL) return root; root->height = 1 + max(height(root->leftChild), height(root->rightChild)); int balance = getBalance(root); if (balance > 1 && getBalance(root->leftChild) >= 0) return rightRotate(root); if (balance > 1 && getBalance(root->leftChild) < 0) { root->leftChild = leftRotate(root->leftChild); return rightRotate(root); } if (balance < -1 && getBalance(root->rightChild) <= 0) return leftRotate(root); if (balance < -1 && getBalance(root->rightChild) > 0) { root->rightChild = rightRotate(root->rightChild); return leftRotate(root); } return root; } // Print the tree void printTree(struct Node *root){ if (root != NULL) { printTree(root->leftChild); printf("%d ", root->data); printTree(root->rightChild); } } int main(){ struct Node *root = NULL; root = insertNode(root, 22); root = insertNode(root, 14); root = insertNode(root, 72); root = insertNode(root, 44); root = insertNode(root, 25); root = insertNode(root, 63); root = insertNode(root, 98); printf("AVL Tree: "); printTree(root); root = deleteNode(root, 25); printf("\nAfter deletion: "); printTree(root); return 0; }輸出
AVL Tree: 14 22 25 44 63 72 98 After deletion: 14 22 44 63 72 98
#include <iostream> struct Node { int data; struct Node *leftChild; struct Node *rightChild; int height; }; int max(int a, int b); int height(struct Node *N){ if (N == NULL) return 0; return N->height; } int max(int a, int b){ return (a > b) ? a : b; } struct Node *newNode(int data){ struct Node *node = (struct Node *) malloc(sizeof(struct Node)); node->data = data; node->leftChild = NULL; node->rightChild = NULL; node->height = 1; return (node); } struct Node *rightRotate(struct Node *y){ struct Node *x = y->leftChild; struct Node *T2 = x->rightChild; x->rightChild = y; y->leftChild = T2; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; return x; } struct Node *leftRotate(struct Node *x){ struct Node *y = x->rightChild; struct Node *T2 = y->leftChild; y->leftChild = x; x->rightChild = T2; x->height = max(height(x->leftChild), height(x->rightChild)) + 1; y->height = max(height(y->leftChild), height(y->rightChild)) + 1; return y; } int getBalance(struct Node *N){ if (N == NULL) return 0; return height(N->leftChild) - height(N->rightChild); } struct Node *insertNode(struct Node *node, int data){ if (node == NULL) return (newNode(data)); if (data < node->data) node->leftChild = insertNode(node->leftChild, data); else if (data > node->data) node->rightChild = insertNode(node->rightChild, data); else return node; node->height = 1 + max(height(node->leftChild), height(node->rightChild)); int balance = getBalance(node); if (balance > 1 && data < node->leftChild->data) return rightRotate(node); if (balance < -1 && data > node->rightChild->data) return leftRotate(node); if (balance > 1 && data > node->leftChild->data) { node->leftChild = leftRotate(node->leftChild); return rightRotate(node); } if (balance < -1 && data < node->rightChild->data) { node->rightChild = rightRotate(node->rightChild); return leftRotate(node); } return node; } struct Node *minValueNode(struct Node *node){ struct Node *current = node; while (current->leftChild != NULL) current = current->leftChild; return current; } struct Node *deleteNode(struct Node *root, int data){ if (root == NULL) return root; if (data < root->data) root->leftChild = deleteNode(root->leftChild, data); else if (data > root->data) root->rightChild = deleteNode(root->rightChild, data); else { if ((root->leftChild == NULL) || (root->rightChild == NULL)) { struct Node *temp = root->leftChild ? root->leftChild : root->rightChild; if (temp == NULL) { temp = root; root = NULL; } else *root = *temp; free(temp); } else { struct Node *temp = minValueNode(root->rightChild); root->data = temp->data; root->rightChild = deleteNode(root->rightChild, temp->data); } } if (root == NULL) return root; root->height = 1 + max(height(root->leftChild), height(root->rightChild)); int balance = getBalance(root); if (balance > 1 && getBalance(root->leftChild) >= 0) return rightRotate(root); if (balance > 1 && getBalance(root->leftChild) < 0) { root->leftChild = leftRotate(root->leftChild); return rightRotate(root); } if (balance < -1 && getBalance(root->rightChild) <= 0) return leftRotate(root); if (balance < -1 && getBalance(root->rightChild) > 0) { root->rightChild = rightRotate(root->rightChild); return leftRotate(root); } return root; } // Print the tree void printTree(struct Node *root){ if (root != NULL) { printTree(root->leftChild); printf("%d ", root->data); printTree(root->rightChild); } } int main(){ struct Node *root = NULL; root = insertNode(root, 22); root = insertNode(root, 14); root = insertNode(root, 72); root = insertNode(root, 44); root = insertNode(root, 25); root = insertNode(root, 63); root = insertNode(root, 98); printf("AVL Tree: "); printTree(root); root = deleteNode(root, 25); printf("\nAfter deletion: "); printTree(root); return 0; }輸出
AVL Tree: 14 22 25 44 63 72 98 After deletion: 14 22 44 63 72 98
import java.util.*; import java.io.*; class Node { int key, height; Node left, right; Node (int d) { key = d; height = 1; } } public class AVLTree { Node root; int height (Node N) { if (N == null) return 0; return N.height; } int max (int a, int b) { return (a > b) ? a : b; } Node rightRotate (Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; y.height = max (height (y.left), height (y.right)) + 1; x.height = max (height (x.left), height (x.right)) + 1; return x; } Node leftRotate (Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; x.height = max (height (x.left), height (x.right)) + 1; y.height = max (height (y.left), height (y.right)) + 1; return y; } int getBalance (Node N) { if (N == null) return 0; return height (N.left) - height (N.right); } Node minValueNode (Node node) { Node current = node; while (current.left != null) current = current.left; return current; } Node deleteNode (Node root, int key) { if (root == null) return root; if (key < root.key) root.left = deleteNode (root.left, key); else if (key > root.key) root.right = deleteNode (root.right, key); else { if ((root.left == null) || (root.right == null)) { Node temp = null; if (temp == root.left) temp = root.right; else temp = root.left; if (temp == null) { temp = root; root = null; } else root = temp; } else { Node temp = minValueNode (root.right); root.key = temp.key; root.right = deleteNode (root.right, temp.key); } } if (root == null) return root; root.height = max (height (root.left), height (root.right)) + 1; int balance = getBalance (root); if (balance > 1 && getBalance (root.left) >= 0) return rightRotate (root); if (balance > 1 && getBalance (root.left) < 0) { root.left = leftRotate (root.left); return rightRotate (root); } if (balance < -1 && getBalance (root.right) <= 0) return leftRotate (root); if (balance < -1 && getBalance (root.right) > 0) { root.right = rightRotate (root.right); return leftRotate (root); } return root; } public void printTree(Node root) { if (root == null) return; printTree(root.left); System.out.print(root.key + " "); printTree(root.right); } public static void main (String[]args) { AVLTree tree = new AVLTree(); tree.root = new Node(13); tree.root.left = new Node(12); tree.root.left.left = new Node(11); tree.root.left.left.left = new Node(10); tree.root.right = new Node(14); tree.root.right.right = new Node(15); System.out.print("AVL Tree: "); tree.printTree(tree.root); tree.root = tree.deleteNode (tree.root, 10); System.out.print("\nAfter deletion: "); tree.printTree(tree.root); System.out.println (""); } }輸出
AVL Tree: 10 11 12 13 14 15 After deletion: 11 12 13 14 15
class Node(object): def __init__(self, data): self.data = data self.left = None self.right = None self.height = 1 class AVLTree(object): def insert(self, root, key): if not root: return Node(key) elif key < root.data: root.left = self.insert(root.left, key) else: root.right = self.insert(root.right, key) root.h = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) b = self.getBalance(root) if b > 1 and key < root.left.data: return self.rightRotate(root) if b < -1 and key > root.right.data: return self.leftRotate(root) if b > 1 and key > root.left.data: root.left = self.lefttRotate(root.left) return self.rightRotate(root) if b < -1 and key < root.right.data: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def delete(self, root, key): if not root: return root elif key < root.data: root.left = self.delete(root.left, key) elif key > root.data: root.right = self.delete(root.right, key) else: if root.left is None: temp = root.right root = None return temp elif root.right is None: temp = root.left root = None return temp temp = self.getMindataueNode(root.right) root.data = temp.data root.right = self.delete(root.right, temp.data) if root is None: return root root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) balance = self.getBalance(root) if balance > 1 and self.getBalance(root.left) >= 0: return self.rightRotate(root) if balance < -1 and self.getBalance(root.right) <= 0: return self.leftRotate(root) if balance > 1 and self.getBalance(root.left) < 0: root.left = self.leftRotate(root.left) return self.rightRotate(root) if balance < -1 and self.getBalance(root.right) > 0: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def leftRotate(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def rightRotate(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def getHeight(self, root): if not root: return 0 return root.height def getBalance(self, root): if not root: return 0 return self.getHeight(root.left) - self.getHeight(root.right) def Inorder(self, root): if root.left: self.Inorder(root.left) print(root.data, end = " ") if root.right: self.Inorder(root.right) Tree = AVLTree() root = None root = Tree.insert(root, 10) root = Tree.insert(root, 13) root = Tree.insert(root, 11) root = Tree.insert(root, 14) root = Tree.insert(root, 12) root = Tree.insert(root, 15) # Inorder Traversal print("AVL Tree: ") Tree.Inorder(root) root = Tree.delete(root, 14) print("\nAfter deletion: ") Tree.Inorder(root)輸出
AVL Tree: 10 11 12 13 14 15 After deletion: 10 11 12 13 15