This commit is contained in:
krahets
2023-04-18 20:19:07 +08:00
parent cf4a59e3d6
commit 363f1f4b5f
25 changed files with 1910 additions and 107 deletions
+180 -11
View File
@@ -70,7 +70,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "Go"
```go title=""
/* AVL 树节点 */
/* AVL 树节点结构体 */
type TreeNode struct {
Val int // 节点值
Height int // 节点高度
@@ -82,6 +82,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "JavaScript"
```javascript title=""
/* AVL 树节点类 */
class TreeNode {
val; // 节点值
height; //节点高度
@@ -99,6 +100,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "TypeScript"
```typescript title=""
/* AVL 树节点类 */
class TreeNode {
val: number; // 节点值
height: number; // 节点高度
@@ -116,7 +118,27 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "C"
```c title=""
/* AVL 树节点结构体 */
struct TreeNode {
int val;
int height;
struct TreeNode *left;
struct TreeNode *right;
};
typedef struct TreeNode TreeNode;
/* 构造函数 */
TreeNode *newTreeNode(int val) {
TreeNode *node;
node = (TreeNode *)malloc(sizeof(TreeNode));
node->val = val;
node->height = 0;
node->left = NULL;
node->right = NULL;
return node;
}
```
=== "C#"
@@ -267,9 +289,26 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{height}
/* 获取节点高度 */
int height(TreeNode *node) {
// 空节点高度为 -1 ,叶节点高度为 0
if (node != NULL) {
return node->height;
}
return -1;
}
[class]{aVLTree}-[func]{updateHeight}
/* 更新节点高度 */
void updateHeight(TreeNode *node) {
int lh = height(node->left);
int rh = height(node->right);
// 节点高度等于最高子树高度 + 1
if (lh > rh) {
node->height = lh + 1;
} else {
node->height = rh + 1;
}
}
```
=== "C#"
@@ -406,7 +445,15 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{balanceFactor}
/* 获取平衡因子 */
int balanceFactor(TreeNode *node) {
// 空节点平衡因子为 0
if (node == NULL) {
return 0;
}
// 节点平衡因子 = 左子树高度 - 右子树高度
return height(node->left) - height(node->right);
}
```
=== "C#"
@@ -590,7 +637,20 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{rightRotate}
/* 右旋操作 */
TreeNode *rightRotate(TreeNode *node) {
TreeNode *child, *grandChild;
child = node->left;
grandChild = child->right;
// 以 child 为原点,将 node 向右旋转
child->right = node;
node->left = grandChild;
// 更新节点高度
updateHeight(node);
updateHeight(child);
// 返回旋转后子树的根节点
return child;
}
```
=== "C#"
@@ -774,7 +834,20 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{leftRotate}
/* 左旋操作 */
TreeNode *leftRotate(TreeNode *node) {
TreeNode *child, *grandChild;
child = node->right;
grandChild = child->left;
// 以 child 为原点,将 node 向左旋转
child->left = node;
node->right = grandChild;
// 更新节点高度
updateHeight(node);
updateHeight(child);
// 返回旋转后子树的根节点
return child;
}
```
=== "C#"
@@ -1074,7 +1147,35 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{rotate}
/* 执行旋转操作,使该子树重新恢复平衡 */
TreeNode *rotate(TreeNode *node) {
// 获取节点 node 的平衡因子
int bf = balanceFactor(node);
// 左偏树
if (bf > 1) {
if (balanceFactor(node->left) >= 0) {
// 右旋
return rightRotate(node);
} else {
// 先左旋后右旋
node->left = leftRotate(node->left);
return rightRotate(node);
}
}
// 右偏树
if (bf < -1) {
if (balanceFactor(node->right) <= 0) {
// 左旋
return leftRotate(node);
} else {
// 先右旋后左旋
node->right = rightRotate(node->right);
return leftRotate(node);
}
}
// 平衡树,无需旋转,直接返回
return node;
}
```
=== "C#"
@@ -1358,9 +1459,32 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{insert}
/* 插入节点 */
void insert(aVLTree *tree, int val) {
tree->root = insertHelper(tree->root, val);
}
[class]{aVLTree}-[func]{insertHelper}
/* 递归插入节点(辅助方法) */
TreeNode *insertHelper(TreeNode *node, int val) {
if (node == NULL) {
return newTreeNode(val);
}
/* 1. 查找插入位置,并插入节点 */
if (val < node->val) {
node->left = insertHelper(node->left, val);
} else if (val > node->val) {
node->right = insertHelper(node->right, val);
} else {
// 重复节点不插入,直接返回
return node;
}
// 更新节点高度
updateHeight(node);
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node);
// 返回子树的根节点
return node;
}
```
=== "C#"
@@ -1726,9 +1850,54 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉
=== "C"
```c title="avl_tree.c"
[class]{aVLTree}-[func]{remove}
/* 删除节点 */
// 由于引入了 stdio.h ,此处无法使用 remove 关键词
void removeNode(aVLTree *tree, int val) {
TreeNode *root = removeHelper(tree->root, val);
}
[class]{aVLTree}-[func]{removeHelper}
/* 递归删除节点(辅助方法) */
TreeNode *removeHelper(TreeNode *node, int val) {
TreeNode *child, *grandChild;
if (node == NULL) {
return NULL;
}
/* 1. 查找节点,并删除之 */
if (val < node->val) {
node->left = removeHelper(node->left, val);
} else if (val > node->val) {
node->right = removeHelper(node->right, val);
} else {
if (node->left == NULL || node->right == NULL) {
child = node->left;
if (node->right != NULL) {
child = node->right;
}
// 子节点数量 = 0 ,直接删除 node 并返回
if (child == NULL) {
return NULL;
} else {
// 子节点数量 = 1 ,直接删除 node
node = child;
}
} else {
// 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点
TreeNode *temp = node->right;
while (temp->left != NULL) {
temp = temp->left;
}
int tempVal = temp->val;
node->right = removeHelper(node->right, temp->val);
node->val = tempVal;
}
}
// 更新节点高度
updateHeight(node);
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node);
// 返回子树的根节点
return node;
}
```
=== "C#"