This commit is contained in:
krahets
2023-02-09 04:43:12 +08:00
parent af3542e3c0
commit 4d2575be7a
18 changed files with 264 additions and 156 deletions
Executable → Regular
+84 -49
View File
@@ -207,7 +207,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
```go title="avl_tree.go"
/* 获取结点高度 */
func height(node *TreeNode) int {
func (t *aVLTree) height(node *TreeNode) int {
// 空结点高度为 -1 ,叶结点高度为 0
if node != nil {
return node.Height
@@ -216,9 +216,9 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
}
/* 更新结点高度 */
func updateHeight(node *TreeNode) {
lh := height(node.Left)
rh := height(node.Right)
func (t *aVLTree) updateHeight(node *TreeNode) {
lh := t.height(node.Left)
rh := t.height(node.Right)
// 结点高度等于最高子树高度 + 1
if lh > rh {
node.Height = lh + 1
@@ -350,13 +350,13 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
```go title="avl_tree.go"
/* 获取平衡因子 */
func balanceFactor(node *TreeNode) int {
func (t *aVLTree) balanceFactor(node *TreeNode) int {
// 空结点平衡因子为 0
if node == nil {
return 0
}
// 结点平衡因子 = 左子树高度 - 右子树高度
return height(node.Left) - height(node.Right)
return t.height(node.Left) - t.height(node.Right)
}
```
@@ -512,15 +512,15 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
```go title="avl_tree.go"
/* 右旋操作 */
func rightRotate(node *TreeNode) *TreeNode {
func (t *aVLTree) rightRotate(node *TreeNode) *TreeNode {
child := node.Left
grandChild := child.Right
// 以 child 为原点,将 node 向右旋转
child.Right = node
node.Left = grandChild
// 更新结点高度
updateHeight(node)
updateHeight(child)
t.updateHeight(node)
t.updateHeight(child)
// 返回旋转后子树的根结点
return child
}
@@ -680,15 +680,15 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
```go title="avl_tree.go"
/* 左旋操作 */
func leftRotate(node *TreeNode) *TreeNode {
func (t *aVLTree) leftRotate(node *TreeNode) *TreeNode {
child := node.Right
grandChild := child.Left
// 以 child 为原点,将 node 向左旋转
child.Left = node
node.Right = grandChild
// 更新结点高度
updateHeight(node)
updateHeight(child)
t.updateHeight(node)
t.updateHeight(child)
// 返回旋转后子树的根结点
return child
}
@@ -915,30 +915,30 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
```go title="avl_tree.go"
/* 执行旋转操作,使该子树重新恢复平衡 */
func rotate(node *TreeNode) *TreeNode {
func (t *aVLTree) rotate(node *TreeNode) *TreeNode {
// 获取结点 node 的平衡因子
// Go 推荐短变量,这里 bf 指代 balanceFactor
bf := balanceFactor(node)
// Go 推荐短变量,这里 bf 指代 t.balanceFactor
bf := t.balanceFactor(node)
// 左偏树
if bf > 1 {
if balanceFactor(node.Left) >= 0 {
if t.balanceFactor(node.Left) >= 0 {
// 右旋
return rightRotate(node)
return t.rightRotate(node)
} else {
// 先左旋后右旋
node.Left = leftRotate(node.Left)
return rightRotate(node)
node.Left = t.leftRotate(node.Left)
return t.rightRotate(node)
}
}
// 右偏树
if bf < -1 {
if balanceFactor(node.Right) <= 0 {
if t.balanceFactor(node.Right) <= 0 {
// 左旋
return leftRotate(node)
return t.leftRotate(node)
} else {
// 先右旋后左旋
node.Right = rightRotate(node.Right)
return leftRotate(node)
node.Right = t.rightRotate(node.Right)
return t.leftRotate(node)
}
}
// 平衡树,无需旋转,直接返回
@@ -1193,28 +1193,29 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
```go title="avl_tree.go"
/* 插入结点 */
func (t *avlTree) insert(val int) *TreeNode {
t.root = insertHelper(t.root, val)
func (t *aVLTree) insert(val int) *TreeNode {
t.root = t.insertHelper(t.root, val)
return t.root
}
/* 递归插入结点(辅助函数) */
func insertHelper(node *TreeNode, val int) *TreeNode {
func (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode {
if node == nil {
return NewTreeNode(val)
}
/* 1. 查找插入位置,并插入结点 */
if val < node.Val {
node.Left = insertHelper(node.Left, val)
node.Left = t.insertHelper(node.Left, val)
} else if val > node.Val {
node.Right = insertHelper(node.Right, val)
node.Right = t.insertHelper(node.Right, val)
} else {
// 重复结点不插入,直接返回
return node
}
// 更新结点高度
updateHeight(node)
t.updateHeight(node)
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node)
node = t.rotate(node)
// 返回子树的根结点
return node
}
@@ -1445,6 +1446,16 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
// 返回子树的根结点
return node;
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
TreeNode* getInOrderNext(TreeNode* node) {
if (node == nullptr) return node;
// 循环访问左子结点,直到叶结点时为最小结点,跳出
while (node->left != nullptr) {
node = node->left;
}
return node;
}
```
=== "Python"
@@ -1481,27 +1492,36 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
self.__update_height(node)
# 2. 执行旋转操作,使该子树重新恢复平衡
return self.__rotate(node)
""" 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """
def __get_inorder_next(self, node: Optional[TreeNode]) -> Optional[TreeNode]:
if node is None:
return None
# 循环访问左子结点,直到叶结点时为最小结点,跳出
while node.left is not None:
node = node.left
return node
```
=== "Go"
```go title="avl_tree.go"
/* 删除结点 */
func (t *avlTree) remove(val int) *TreeNode {
root := removeHelper(t.root, val)
func (t *aVLTree) remove(val int) *TreeNode {
root := t.removeHelper(t.root, val)
return root
}
/* 递归删除结点(辅助函数) */
func removeHelper(node *TreeNode, val int) *TreeNode {
func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode {
if node == nil {
return nil
}
/* 1. 查找结点,并删除之 */
if val < node.Val {
node.Left = removeHelper(node.Left, val)
node.Left = t.removeHelper(node.Left, val)
} else if val > node.Val {
node.Right = removeHelper(node.Right, val)
node.Right = t.removeHelper(node.Right, val)
} else {
if node.Left == nil || node.Right == nil {
child := node.Left
@@ -1517,18 +1537,30 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
}
} else {
// 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点
temp := getInOrderNext(node.Right)
node.Right = removeHelper(node.Right, temp.Val)
temp := t.getInOrderNext(node.Right)
node.Right = t.removeHelper(node.Right, temp.Val)
node.Val = temp.Val
}
}
// 更新结点高度
updateHeight(node)
t.updateHeight(node)
/* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node)
node = t.rotate(node)
// 返回子树的根结点
return node
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
func (t *aVLTree) getInOrderNext(node *TreeNode) *TreeNode {
if node == nil {
return node
}
// 循环访问左子结点,直到叶结点时为最小结点,跳出
for node.Left != nil {
node = node.Left
}
return node
}
```
=== "JavaScript"
@@ -1567,16 +1599,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
return node;
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
getInOrderNext(node) {
if (node === null) return node;
// 循环访问左子结点,直到叶结点时为最小结点,跳出
while (node.left !== null) {
node = node.left;
}
return node;
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
getInOrderNext(node) {
if (node === null) return node;
@@ -1750,6 +1772,19 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
// 返回子树的根结点
return node
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
func getInOrderNext(node: TreeNode?) -> TreeNode? {
var node = node
if node == nil {
return node
}
// 循环访问左子结点,直到叶结点时为最小结点,跳出
while node?.left != nil {
node = node?.left
}
return node
}
```
=== "Zig"
+3 -3
View File
@@ -86,7 +86,7 @@ comments: true
```go title="binary_tree_bfs.go"
/* 层序遍历 */
func levelOrder(root *TreeNode) []int {
func hierOrder(root *TreeNode) []int {
// 初始化队列,加入根结点
queue := list.New()
queue.PushBack(root)
@@ -340,7 +340,7 @@ comments: true
preOrder(node.Left)
preOrder(node.Right)
}
/* 中序遍历 */
func inOrder(node *TreeNode) {
if node == nil {
@@ -351,7 +351,7 @@ comments: true
nums = append(nums, node.Val)
inOrder(node.Right)
}
/* 后序遍历 */
func postOrder(node *TreeNode) {
if node == nil {