From f7ae9c8a024c604d32f65501ee44315f234d52ca Mon Sep 17 00:00:00 2001 From: krahets Date: Fri, 14 Apr 2023 05:47:20 +0800 Subject: [PATCH] Fix the return type of binary search tree and avl tree --- codes/c/chapter_tree/avl_tree.c | 21 ++++----- codes/c/chapter_tree/binary_search_tree.c | 44 ++++++++----------- codes/cpp/chapter_tree/avl_tree.cpp | 24 ++++------ codes/cpp/chapter_tree/binary_search_tree.cpp | 42 +++++++----------- codes/csharp/chapter_tree/avl_tree.cs | 24 +++------- .../csharp/chapter_tree/binary_search_tree.cs | 42 ++++++------------ codes/dart/chapter_tree/avl_tree.dart | 21 +++------ .../dart/chapter_tree/binary_search_tree.dart | 38 ++++++---------- codes/go/chapter_tree/avl_tree.go | 27 ++++-------- codes/go/chapter_tree/binary_search_tree.go | 40 ++++++----------- .../chapter_tree/binary_search_tree_test.go | 2 +- codes/java/chapter_tree/avl_tree.java | 22 +++------- .../java/chapter_tree/binary_search_tree.java | 30 ++++++------- codes/javascript/chapter_tree/avl_tree.js | 17 ++----- .../chapter_tree/binary_search_tree.js | 36 ++++++--------- codes/python/chapter_tree/avl_tree.py | 22 +++------- .../python/chapter_tree/binary_search_tree.py | 44 ++++++++----------- codes/swift/chapter_tree/avl_tree.swift | 24 +++------- .../chapter_tree/binary_search_tree.swift | 43 +++++++----------- codes/typescript/chapter_tree/avl_tree.ts | 21 +++------ .../chapter_tree/binary_search_tree.ts | 42 +++++++----------- codes/zig/chapter_tree/avl_tree.zig | 25 +++-------- codes/zig/chapter_tree/binary_search_tree.zig | 41 +++++++---------- docs/chapter_tree/binary_search_tree.md | 6 +-- 24 files changed, 247 insertions(+), 451 deletions(-) diff --git a/codes/c/chapter_tree/avl_tree.c b/codes/c/chapter_tree/avl_tree.c index 432cd5d7..3a148c3a 100644 --- a/codes/c/chapter_tree/avl_tree.c +++ b/codes/c/chapter_tree/avl_tree.c @@ -15,7 +15,7 @@ typedef struct avlTree avlTree; /* 构建 AVL 树 */ avlTree *newAVLTree() { - avlTree *tree = (avlTree *) malloc(sizeof(avlTree)); + avlTree *tree = (avlTree *)malloc(sizeof(avlTree)); tree->root = NULL; return tree; } @@ -132,11 +132,9 @@ TreeNode *insertHelper(TreeNode *node, int val) { return node; } - /* 插入节点 */ -TreeNode *insert(avlTree *tree, int val) { +void insert(avlTree *tree, int val) { tree->root = insertHelper(tree->root, val); - return tree->root; } /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ @@ -153,7 +151,7 @@ TreeNode *getInOrderNext(TreeNode *node) { /* 递归删除节点(辅助方法) */ TreeNode *removeHelper(TreeNode *node, int val) { - TreeNode *child, *grandChild, *temp; + TreeNode *child, *grandChild; if (node == NULL) { return NULL; } @@ -177,9 +175,13 @@ TreeNode *removeHelper(TreeNode *node, int val) { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - temp = getInOrderNext(node->right); + TreeNode *temp = node->right; + while (temp->left != NULL) { + temp = temp->left; + } + int tempVal = temp->val; node->right = removeHelper(node->right, temp->val); - node->val = temp->val; + node->val = tempVal; } } // 更新节点高度 @@ -192,9 +194,8 @@ TreeNode *removeHelper(TreeNode *node, int val) { /* 删除节点 */ // 由于引入了 stdio.h ,此处无法使用 remove 关键词 -TreeNode *removeNode(avlTree *tree, int val) { +void removeNode(avlTree *tree, int val) { TreeNode *root = removeHelper(tree->root, val); - return root; } /* 查找节点 */ @@ -232,7 +233,7 @@ void testRemove(avlTree *tree, int val) { /* Driver Code */ int main() { /* 初始化空 AVL 树 */ - avlTree *tree = (avlTree *) newAVLTree(); + avlTree *tree = (avlTree *)newAVLTree(); /* 插入节点 */ // 请关注插入节点后,AVL 树是如何保持平衡的 testInsert(tree, 1); diff --git a/codes/c/chapter_tree/binary_search_tree.c b/codes/c/chapter_tree/binary_search_tree.c index 1039c24f..c207ddd3 100644 --- a/codes/c/chapter_tree/binary_search_tree.c +++ b/codes/c/chapter_tree/binary_search_tree.c @@ -69,15 +69,16 @@ TreeNode *search(binarySearchTree *bst, int num) { } /* 插入节点 */ -TreeNode *insert(binarySearchTree *bst, int num) { +void insert(binarySearchTree *bst, int num) { // 若树为空,直接提前返回 - if (bst->root == NULL) return NULL; + if (bst->root == NULL) + return; TreeNode *cur = bst->root, *pre = NULL; // 循环查找,越过叶节点后跳出 while (cur != NULL) { // 找到重复节点,直接返回 if (cur->val == num) { - return NULL; + return; } pre = cur; if (cur->val < num) { @@ -95,24 +96,14 @@ TreeNode *insert(binarySearchTree *bst, int num) { } else { pre->left = node; } - return node; -} - -/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ -TreeNode *getInOrderNext(TreeNode *root) { - if (root == NULL) return root; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root->left != NULL) { - root = root->left; - } - return root; } /* 删除节点 */ // 由于引入了 stdio.h ,此处无法使用 remove 关键词 -TreeNode *removeNode(binarySearchTree *bst, int num) { +void removeNode(binarySearchTree *bst, int num) { // 若树为空,直接提前返回 - if (bst->root == NULL) return NULL; + if (bst->root == NULL) + return; TreeNode *cur = bst->root, *pre = NULL; // 循环查找,越过叶节点后跳出 while (cur != NULL) { @@ -128,9 +119,8 @@ TreeNode *removeNode(binarySearchTree *bst, int num) { } } // 若无待删除节点,则直接返回 - if (cur == NULL) { - return NULL; - } + if (cur == NULL) + return; // 判断待删除节点是否存在子节点 if (cur->left == NULL || cur->right == NULL) { /* 子节点数量 = 0 or 1 */ @@ -145,14 +135,16 @@ TreeNode *removeNode(binarySearchTree *bst, int num) { } else { /* 子节点数量 = 2 */ // 获取中序遍历中 cur 的下一个节点 - TreeNode *nex = getInOrderNext(cur->right); - int tmp = nex->val; - // 递归删除节点 nex - removeNode(bst, nex->val); - // 将 nex 的值复制给 cur - cur->val = tmp; + TreeNode *tmp = cur->right; + while (tmp->left != NULL) { + tmp = tmp->left; + } + int tmpVal = tmp->val; + // 递归删除节点 tmp + removeNode(bst, tmp->val); + // 用 tmp 覆盖 cur + cur->val = tmpVal; } - return cur; } /* Driver Code */ diff --git a/codes/cpp/chapter_tree/avl_tree.cpp b/codes/cpp/chapter_tree/avl_tree.cpp index 2cc89459..82e01d44 100644 --- a/codes/cpp/chapter_tree/avl_tree.cpp +++ b/codes/cpp/chapter_tree/avl_tree.cpp @@ -93,17 +93,6 @@ class AVLTree { return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - TreeNode *getInOrderNext(TreeNode *node) { - if (node == nullptr) - return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node->left != nullptr) { - node = node->left; - } - return node; - } - /* 递归删除节点(辅助方法) */ TreeNode *removeHelper(TreeNode *node, int val) { if (node == nullptr) @@ -128,7 +117,10 @@ class AVLTree { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - TreeNode *temp = getInOrderNext(node->right); + TreeNode *temp = node->right; + while (temp->left != nullptr) { + temp = temp->left; + } int tempVal = temp->val; node->right = removeHelper(node->right, temp->val); node->val = tempVal; @@ -158,15 +150,13 @@ class AVLTree { } /* 插入节点 */ - TreeNode *insert(int val) { + void insert(int val) { root = insertHelper(root, val); - return root; } /* 删除节点 */ - TreeNode *remove(int val) { + void remove(int val) { root = removeHelper(root, val); - return root; } /* 查找节点 */ @@ -209,6 +199,8 @@ void testRemove(AVLTree &tree, int val) { cout << "\n删除节点 " << val << " 后,AVL 树为" << endl; printTree(tree.root); } + +/* Driver Code */ int main() { /* 初始化空 AVL 树 */ AVLTree avlTree; diff --git a/codes/cpp/chapter_tree/binary_search_tree.cpp b/codes/cpp/chapter_tree/binary_search_tree.cpp index 08bedbef..022afeca 100644 --- a/codes/cpp/chapter_tree/binary_search_tree.cpp +++ b/codes/cpp/chapter_tree/binary_search_tree.cpp @@ -59,16 +59,16 @@ class BinarySearchTree { } /* 插入节点 */ - TreeNode *insert(int num) { + void insert(int num) { // 若树为空,直接提前返回 if (root == nullptr) - return nullptr; + return; TreeNode *cur = root, *pre = nullptr; // 循环查找,越过叶节点后跳出 while (cur != nullptr) { // 找到重复节点,直接返回 if (cur->val == num) - return nullptr; + return; pre = cur; // 插入位置在 cur 的右子树中 if (cur->val < num) @@ -83,14 +83,13 @@ class BinarySearchTree { pre->right = node; else pre->left = node; - return node; } /* 删除节点 */ - TreeNode *remove(int num) { + void remove(int num) { // 若树为空,直接提前返回 if (root == nullptr) - return nullptr; + return; TreeNode *cur = root, *pre = nullptr; // 循环查找,越过叶节点后跳出 while (cur != nullptr) { @@ -107,7 +106,7 @@ class BinarySearchTree { } // 若无待删除节点,则直接返回 if (cur == nullptr) - return nullptr; + return; // 子节点数量 = 0 or 1 if (cur->left == nullptr || cur->right == nullptr) { // 当子节点数量 = 0 / 1 时, child = nullptr / 该子节点 @@ -123,25 +122,16 @@ class BinarySearchTree { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - TreeNode *nex = getInOrderNext(cur->right); - int tmp = nex->val; - // 递归删除节点 nex - remove(nex->val); - // 将 nex 的值复制给 cur - cur->val = tmp; + TreeNode *tmp = cur->right; + while (tmp->left != nullptr) { + tmp = tmp->left; + } + int tmpVal = tmp->val; + // 递归删除节点 tmp + remove(tmp->val); + // 用 tmp 覆盖 cur + cur->val = tmpVal; } - return cur; - } - - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - TreeNode *getInOrderNext(TreeNode *root) { - if (root == nullptr) - return root; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root->left != nullptr) { - root = root->left; - } - return root; } }; @@ -158,7 +148,7 @@ int main() { cout << endl << "查找到的节点对象为 " << node << ",节点值 = " << node->val << endl; /* 插入节点 */ - node = bst->insert(16); + bst->insert(16); cout << endl << "插入节点 16 后,二叉树为\n" << endl; printTree(bst->getRoot()); diff --git a/codes/csharp/chapter_tree/avl_tree.cs b/codes/csharp/chapter_tree/avl_tree.cs index 70d3282a..64b7cf37 100644 --- a/codes/csharp/chapter_tree/avl_tree.cs +++ b/codes/csharp/chapter_tree/avl_tree.cs @@ -107,10 +107,9 @@ class AVLTree } /* 插入节点 */ - public TreeNode? insert(int val) + public void insert(int val) { root = insertHelper(root, val); - return root; } /* 递归插入节点(辅助方法) */ @@ -132,10 +131,9 @@ class AVLTree } /* 删除节点 */ - public TreeNode? remove(int val) + public void remove(int val) { root = removeHelper(root, val); - return root; } /* 递归删除节点(辅助方法) */ @@ -162,7 +160,11 @@ class AVLTree else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - TreeNode? temp = getInOrderNext(node.right); + TreeNode? temp = node.right; + while (temp.left != null) + { + temp = temp.left; + } node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -174,18 +176,6 @@ class AVLTree return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - private TreeNode? getInOrderNext(TreeNode? node) - { - if (node == null) return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node.left != null) - { - node = node.left; - } - return node; - } - /* 查找节点 */ public TreeNode? search(int val) { diff --git a/codes/csharp/chapter_tree/binary_search_tree.cs b/codes/csharp/chapter_tree/binary_search_tree.cs index b4eae044..f3a56d3f 100644 --- a/codes/csharp/chapter_tree/binary_search_tree.cs +++ b/codes/csharp/chapter_tree/binary_search_tree.cs @@ -57,16 +57,16 @@ class BinarySearchTree } /* 插入节点 */ - public TreeNode? insert(int num) + public void insert(int num) { // 若树为空,直接提前返回 - if (root == null) return null; + if (root == null) return; TreeNode? cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { // 找到重复节点,直接返回 - if (cur.val == num) return null; + if (cur.val == num) return; pre = cur; // 插入位置在 cur 的右子树中 if (cur.val < num) cur = cur.right; @@ -81,15 +81,14 @@ class BinarySearchTree if (pre.val < num) pre.right = node; else pre.left = node; } - return node; } /* 删除节点 */ - public TreeNode? remove(int num) + public void remove(int num) { // 若树为空,直接提前返回 - if (root == null) return null; + if (root == null) return; TreeNode? cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) @@ -103,7 +102,7 @@ class BinarySearchTree else cur = cur.left; } // 若无待删除节点,则直接返回 - if (cur == null || pre == null) return null; + if (cur == null || pre == null) return; // 子节点数量 = 0 or 1 if (cur.left == null || cur.right == null) { @@ -123,29 +122,16 @@ class BinarySearchTree else { // 获取中序遍历中 cur 的下一个节点 - TreeNode? nex = getInOrderNext(cur.right); - if (nex != null) + TreeNode? tmp = cur.right; + while (tmp.left != null) { - int tmp = nex.val; - // 递归删除节点 nex - remove(nex.val); - // 将 nex 的值复制给 cur - cur.val = tmp; + tmp = tmp.left; } + // 递归删除节点 tmp + remove(tmp.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - return cur; - } - - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - private TreeNode? getInOrderNext(TreeNode? root) - { - if (root == null) return root; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root.left != null) - { - root = root.left; - } - return root; } } @@ -165,7 +151,7 @@ public class binary_search_tree Console.WriteLine("\n查找到的节点对象为 " + node + ",节点值 = " + node.val); /* 插入节点 */ - node = bst.insert(16); + bst.insert(16); Console.WriteLine("\n插入节点 16 后,二叉树为\n"); PrintUtil.PrintTree(bst.getRoot()); diff --git a/codes/dart/chapter_tree/avl_tree.dart b/codes/dart/chapter_tree/avl_tree.dart index 39e7bcb2..379f6868 100644 --- a/codes/dart/chapter_tree/avl_tree.dart +++ b/codes/dart/chapter_tree/avl_tree.dart @@ -94,9 +94,8 @@ class AVLTree { } /* 插入节点 */ - TreeNode? insert(int val) { + void insert(int val) { root = insertHelper(root, val); - return root; } /* 递归插入节点(辅助方法) */ @@ -117,9 +116,8 @@ class AVLTree { } /* 删除节点 */ - TreeNode? remove(int val) { + void remove(int val) { root = removeHelper(root, val); - return root; } /* 递归删除节点(辅助方法) */ @@ -141,7 +139,10 @@ class AVLTree { node = child; } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - TreeNode? temp = getInOrderNext(node.right); + TreeNode? temp = node.right; + while (temp!.left != null) { + temp = temp.left; + } node.right = removeHelper(node.right, temp!.val); node.val = temp.val; } @@ -153,16 +154,6 @@ class AVLTree { return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - TreeNode? getInOrderNext(TreeNode? node) { - if (node == null) return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node!.left != null) { - node = node.left; - } - return node; - } - /* 查找节点 */ TreeNode? search(int val) { TreeNode? cur = root; diff --git a/codes/dart/chapter_tree/binary_search_tree.dart b/codes/dart/chapter_tree/binary_search_tree.dart index a775085c..5c172e54 100644 --- a/codes/dart/chapter_tree/binary_search_tree.dart +++ b/codes/dart/chapter_tree/binary_search_tree.dart @@ -53,15 +53,15 @@ TreeNode? search(int num) { } /* 插入节点 */ -TreeNode? insert(int num) { +void insert(int num) { // 若树为空,直接提前返回 - if (root == null) return null; + if (root == null) return; TreeNode? cur = root; TreeNode? pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { // 找到重复节点,直接返回 - if (cur.val == num) return null; + if (cur.val == num) return; pre = cur; // 插入位置在 cur 的右子树中 if (cur.val < num) @@ -76,13 +76,12 @@ TreeNode? insert(int num) { pre.right = node; else pre.left = node; - return node; } /* 删除节点 */ -TreeNode? remove(int num) { +void remove(int num) { // 若树为空,直接提前返回 - if (root == null) return null; + if (root == null) return; TreeNode? cur = root; TreeNode? pre = null; @@ -99,7 +98,7 @@ TreeNode? remove(int num) { cur = cur.left; } // 若无待删除节点,直接返回 - if (cur == null) return null; + if (cur == null) return; // 子节点数量 = 0 or 1 if (cur.left == null || cur.right == null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 @@ -112,24 +111,15 @@ TreeNode? remove(int num) { } else { // 子节点数量 = 2 // 获取中序遍历中 cur 的下一个节点 - TreeNode? nex = getInOrderNext(cur.right); - int tem = nex!.val; - // 递归删除节点 nex - remove(nex.val); - // 将 nex 的值复制给 cur - cur.val = tem; + TreeNode? tmp = cur.right; + while (tmp!.left != null) { + tmp = tmp.left; + } + // 递归删除节点 tmp + remove(tmp.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - return cur; -} - -/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ -TreeNode? getInOrderNext(TreeNode? root) { - if (root == null) return null; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root!.left != null) { - root = root.left; - } - return root; } /* Driver Code */ diff --git a/codes/go/chapter_tree/avl_tree.go b/codes/go/chapter_tree/avl_tree.go index d57cdff1..b6ba06c6 100644 --- a/codes/go/chapter_tree/avl_tree.go +++ b/codes/go/chapter_tree/avl_tree.go @@ -107,9 +107,8 @@ func (t *aVLTree) rotate(node *TreeNode) *TreeNode { } /* 插入节点 */ -func (t *aVLTree) insert(val int) *TreeNode { +func (t *aVLTree) insert(val int) { t.root = t.insertHelper(t.root, val) - return t.root } /* 递归插入节点(辅助方法) */ @@ -135,9 +134,8 @@ func (t *aVLTree) insertHelper(node *TreeNode, val int) *TreeNode { } /* 删除节点 */ -func (t *aVLTree) remove(val int) *TreeNode { - root := t.removeHelper(t.root, val) - return root +func (t *aVLTree) remove(val int) { + t.root = t.removeHelper(t.root, val) } /* 递归删除节点(辅助方法) */ @@ -156,8 +154,8 @@ func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode { if node.Right != nil { child = node.Right } - // 子节点数量 = 0 ,直接删除 node 并返回 if child == nil { + // 子节点数量 = 0 ,直接删除 node 并返回 return nil } else { // 子节点数量 = 1 ,直接删除 node @@ -165,7 +163,10 @@ func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - temp := t.getInOrderNext(node.Right) + temp := node.Right + for temp.Left != nil { + temp = temp.Left + } node.Right = t.removeHelper(node.Right, temp.Val) node.Val = temp.Val } @@ -178,18 +179,6 @@ func (t *aVLTree) removeHelper(node *TreeNode, val int) *TreeNode { return node } -/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ -func (t *aVLTree) getInOrderNext(node *TreeNode) *TreeNode { - if node == nil { - return node - } - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - for node.Left != nil { - node = node.Left - } - return node -} - /* 查找节点 */ func (t *aVLTree) search(val int) *TreeNode { cur := t.root diff --git a/codes/go/chapter_tree/binary_search_tree.go b/codes/go/chapter_tree/binary_search_tree.go index a4cb8596..6cb6554e 100644 --- a/codes/go/chapter_tree/binary_search_tree.go +++ b/codes/go/chapter_tree/binary_search_tree.go @@ -42,18 +42,6 @@ func (bst *binarySearchTree) getRoot() *TreeNode { return bst.root } -/* 获取中序遍历的下一个节点(仅适用于 root 有左子节点的情况) */ -func (bst *binarySearchTree) getInOrderNext(node *TreeNode) *TreeNode { - if node == nil { - return node - } - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - for node.Left != nil { - node = node.Left - } - return node -} - /* 查找节点 */ func (bst *binarySearchTree) search(num int) *TreeNode { node := bst.root @@ -75,18 +63,18 @@ func (bst *binarySearchTree) search(num int) *TreeNode { } /* 插入节点 */ -func (bst *binarySearchTree) insert(num int) *TreeNode { +func (bst *binarySearchTree) insert(num int) { cur := bst.root // 若树为空,直接提前返回 if cur == nil { - return nil + return } // 待插入节点之前的节点位置 var pre *TreeNode = nil // 循环查找,越过叶节点后跳出 for cur != nil { if cur.Val == num { - return nil + return } pre = cur if cur.Val < num { @@ -102,15 +90,14 @@ func (bst *binarySearchTree) insert(num int) *TreeNode { } else { pre.Left = node } - return cur } /* 删除节点 */ -func (bst *binarySearchTree) remove(num int) *TreeNode { +func (bst *binarySearchTree) remove(num int) { cur := bst.root // 若树为空,直接提前返回 if cur == nil { - return nil + return } // 待删除节点之前的节点位置 var pre *TreeNode = nil @@ -130,7 +117,7 @@ func (bst *binarySearchTree) remove(num int) *TreeNode { } // 若无待删除节点,则直接返回 if cur == nil { - return nil + return } // 子节点数为 0 或 1 if cur.Left == nil || cur.Right == nil { @@ -150,14 +137,15 @@ func (bst *binarySearchTree) remove(num int) *TreeNode { // 子节点数为 2 } else { // 获取中序遍历中待删除节点 cur 的下一个节点 - next := bst.getInOrderNext(cur) - temp := next.Val - // 递归删除节点 next - bst.remove(next.Val) - // 将 next 的值复制给 cur - cur.Val = temp + tmp := cur.Right + for tmp.Left != nil { + tmp = tmp.Left + } + // 递归删除节点 tmp + bst.remove(tmp.Val) + // 用 tmp 覆盖 cur + cur.Val = tmp.Val } - return cur } /* 打印二叉搜索树 */ diff --git a/codes/go/chapter_tree/binary_search_tree_test.go b/codes/go/chapter_tree/binary_search_tree_test.go index 4f87ee7a..2733adb1 100644 --- a/codes/go/chapter_tree/binary_search_tree_test.go +++ b/codes/go/chapter_tree/binary_search_tree_test.go @@ -24,7 +24,7 @@ func TestBinarySearchTree(t *testing.T) { fmt.Println("查找到的节点对象为", node, ",节点值 =", node.Val) // 插入节点 - node = bst.insert(16) + bst.insert(16) fmt.Println("\n插入节点后 16 的二叉树为:") bst.print() diff --git a/codes/java/chapter_tree/avl_tree.java b/codes/java/chapter_tree/avl_tree.java index 70a5340b..aea19fa5 100644 --- a/codes/java/chapter_tree/avl_tree.java +++ b/codes/java/chapter_tree/avl_tree.java @@ -92,9 +92,8 @@ class AVLTree { } /* 插入节点 */ - public TreeNode insert(int val) { + public void insert(int val) { root = insertHelper(root, val); - return root; } /* 递归插入节点(辅助方法) */ @@ -116,9 +115,8 @@ class AVLTree { } /* 删除节点 */ - public TreeNode remove(int val) { + public void remove(int val) { root = removeHelper(root, val); - return root; } /* 递归删除节点(辅助方法) */ @@ -141,7 +139,10 @@ class AVLTree { node = child; } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - TreeNode temp = getInOrderNext(node.right); + TreeNode temp = node.right; + while (temp.left != null) { + temp = temp.left; + } node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -153,17 +154,6 @@ class AVLTree { return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - private TreeNode getInOrderNext(TreeNode node) { - if (node == null) - return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node.left != null) { - node = node.left; - } - return node; - } - /* 查找节点 */ public TreeNode search(int val) { TreeNode cur = root; diff --git a/codes/java/chapter_tree/binary_search_tree.java b/codes/java/chapter_tree/binary_search_tree.java index 0f81d409..8565b7be 100644 --- a/codes/java/chapter_tree/binary_search_tree.java +++ b/codes/java/chapter_tree/binary_search_tree.java @@ -56,16 +56,16 @@ class BinarySearchTree { } /* 插入节点 */ - public TreeNode insert(int num) { + public void insert(int num) { // 若树为空,直接提前返回 if (root == null) - return null; + return; TreeNode cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { // 找到重复节点,直接返回 if (cur.val == num) - return null; + return; pre = cur; // 插入位置在 cur 的右子树中 if (cur.val < num) @@ -80,14 +80,13 @@ class BinarySearchTree { pre.right = node; else pre.left = node; - return node; } /* 删除节点 */ - public TreeNode remove(int num) { + public void remove(int num) { // 若树为空,直接提前返回 if (root == null) - return null; + return; TreeNode cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur != null) { @@ -104,7 +103,7 @@ class BinarySearchTree { } // 若无待删除节点,则直接返回 if (cur == null) - return null; + return; // 子节点数量 = 0 or 1 if (cur.left == null || cur.right == null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 @@ -118,14 +117,15 @@ class BinarySearchTree { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - TreeNode nex = getInOrderNext(cur.right); - int tmp = nex.val; - // 递归删除节点 nex - remove(nex.val); - // 将 nex 的值复制给 cur - cur.val = tmp; + TreeNode tmp = cur.right; + while (tmp.left != null) { + tmp = tmp.left; + } + // 递归删除节点 tmp + remove(tmp.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - return cur; } /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ @@ -153,7 +153,7 @@ public class binary_search_tree { System.out.println("\n查找到的节点对象为 " + node + ",节点值 = " + node.val); /* 插入节点 */ - node = bst.insert(16); + bst.insert(16); System.out.println("\n插入节点 16 后,二叉树为\n"); PrintUtil.printTree(bst.getRoot()); diff --git a/codes/javascript/chapter_tree/avl_tree.js b/codes/javascript/chapter_tree/avl_tree.js index 13a9d6ee..0648c2e7 100644 --- a/codes/javascript/chapter_tree/avl_tree.js +++ b/codes/javascript/chapter_tree/avl_tree.js @@ -95,7 +95,6 @@ class AVLTree { /* 插入节点 */ insert(val) { this.root = this.#insertHelper(this.root, val); - return this.root; } /* 递归插入节点(辅助方法) */ @@ -115,7 +114,6 @@ class AVLTree { /* 删除节点 */ remove(val) { this.root = this.#removeHelper(this.root, val); - return this.root; } /* 递归删除节点(辅助方法) */ @@ -133,7 +131,10 @@ class AVLTree { else node = child; } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - const temp = this.#getInOrderNext(node.right); + let temp = node.right; + while (temp.left !== null) { + temp = temp.left; + } node.right = this.#removeHelper(node.right, temp.val); node.val = temp.val; } @@ -145,16 +146,6 @@ class AVLTree { return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - #getInOrderNext(node) { - if (node === null) return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node.left !== null) { - node = node.left; - } - return node; - } - /* 查找节点 */ search(val) { let cur = this.root; diff --git a/codes/javascript/chapter_tree/binary_search_tree.js b/codes/javascript/chapter_tree/binary_search_tree.js index 2ed342d7..15847953 100644 --- a/codes/javascript/chapter_tree/binary_search_tree.js +++ b/codes/javascript/chapter_tree/binary_search_tree.js @@ -51,12 +51,12 @@ function search(num) { /* 插入节点 */ function insert(num) { // 若树为空,直接提前返回 - if (root === null) return null; + if (root === null) return; let cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur !== null) { // 找到重复节点,直接返回 - if (cur.val === num) return null; + if (cur.val === num) return; pre = cur; // 插入位置在 cur 的右子树中 if (cur.val < num) cur = cur.right; @@ -67,13 +67,12 @@ function insert(num) { let node = new TreeNode(num); if (pre.val < num) pre.right = node; else pre.left = node; - return node; } /* 删除节点 */ function remove(num) { // 若树为空,直接提前返回 - if (root === null) return null; + if (root === null) return; let cur = root, pre = null; // 循环查找,越过叶节点后跳出 while (cur !== null) { @@ -86,7 +85,7 @@ function remove(num) { else cur = cur.left; } // 若无待删除节点,则直接返回 - if (cur === null) return null; + if (cur === null) return; // 子节点数量 = 0 or 1 if (cur.left === null || cur.right === null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 @@ -98,24 +97,15 @@ function remove(num) { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - let nex = getInOrderNext(cur.right); - let tmp = nex.val; - // 递归删除节点 nex - remove(nex.val); - // 将 nex 的值复制给 cur - cur.val = tmp; + let tmp = cur.right; + while (tmp.left !== null) { + tmp = tmp.left; + } + // 递归删除节点 tmp + remove(tmp.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - return cur; -} - -/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ -function getInOrderNext(root) { - if (root === null) return root; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root.left !== null) { - root = root.left; - } - return root; } /* Driver Code */ @@ -130,7 +120,7 @@ let node = search(7); console.log("\n查找到的节点对象为 " + node + ",节点值 = " + node.val); /* 插入节点 */ -node = insert(16); +insert(16); console.log("\n插入节点 16 后,二叉树为\n"); printTree(getRoot()); diff --git a/codes/python/chapter_tree/avl_tree.py b/codes/python/chapter_tree/avl_tree.py index e439eaff..6fe4676f 100644 --- a/codes/python/chapter_tree/avl_tree.py +++ b/codes/python/chapter_tree/avl_tree.py @@ -92,10 +92,9 @@ class AVLTree: # 平衡树,无需旋转,直接返回 return node - def insert(self, val) -> TreeNode: + def insert(self, val) -> None: """插入节点""" self.__root = self.__insert_helper(self.__root, val) - return self.__root def __insert_helper(self, node: TreeNode | None, val: int) -> TreeNode: """递归插入节点(辅助方法)""" @@ -114,10 +113,9 @@ class AVLTree: # 2. 执行旋转操作,使该子树重新恢复平衡 return self.__rotate(node) - def remove(self, val: int) -> TreeNode | None: + def remove(self, val: int) -> None: """删除节点""" self.__root = self.__remove_helper(self.__root, val) - return self.__root def __remove_helper(self, node: TreeNode | None, val: int) -> TreeNode | None: """递归删除节点(辅助方法)""" @@ -137,8 +135,11 @@ class AVLTree: # 子节点数量 = 1 ,直接删除 node else: node = child - else: # 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - temp = self.__get_inorder_next(node.right) + else: + # 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 + temp = node.right + while temp.left is not None: + temp = temp.left node.right = self.__remove_helper(node.right, temp.val) node.val = temp.val # 更新节点高度 @@ -146,15 +147,6 @@ class AVLTree: # 2. 执行旋转操作,使该子树重新恢复平衡 return self.__rotate(node) - def __get_inorder_next(self, node: TreeNode | None) -> TreeNode | None: - """获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况)""" - if node is None: - return None - # 循环访问左子节点,直到叶节点时为最小节点,跳出 - while node.left is not None: - node = node.left - return node - def search(self, val: int) -> TreeNode | None: """查找节点""" cur = self.__root diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index 4ae45d69..fc9b98cc 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -57,18 +57,18 @@ class BinarySearchTree: break return cur - def insert(self, num: int) -> TreeNode | None: + def insert(self, num: int) -> None: """插入节点""" # 若树为空,直接提前返回 if self.__root is None: - return None + return # 循环查找,越过叶节点后跳出 cur, pre = self.__root, None while cur is not None: # 找到重复节点,直接返回 if cur.val == num: - return None + return pre = cur # 插入位置在 cur 的右子树中 if cur.val < num: @@ -83,13 +83,12 @@ class BinarySearchTree: pre.right = node else: pre.left = node - return node - def remove(self, num: int) -> TreeNode | None: + def remove(self, num: int) -> None: """删除节点""" # 若树为空,直接提前返回 if self.__root is None: - return None + return # 循环查找,越过叶节点后跳出 cur, pre = self.__root, None @@ -98,13 +97,15 @@ class BinarySearchTree: if cur.val == num: break pre = cur - if cur.val < num: # 待删除节点在 cur 的右子树中 + # 待删除节点在 cur 的右子树中 + if cur.val < num: cur = cur.right - else: # 待删除节点在 cur 的左子树中 + # 待删除节点在 cur 的左子树中 + else: cur = cur.left # 若无待删除节点,则直接返回 if cur is None: - return None + return # 子节点数量 = 0 or 1 if cur.left is None or cur.right is None: @@ -118,22 +119,13 @@ class BinarySearchTree: # 子节点数量 = 2 else: # 获取中序遍历中 cur 的下一个节点 - nex: TreeNode = self.get_inorder_next(cur.right) - tmp: int = nex.val - # 递归删除节点 nex - self.remove(nex.val) - # 将 nex 的值复制给 cur - cur.val = tmp - return cur - - def get_inorder_next(self, root: TreeNode | None) -> TreeNode | None: - """获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况)""" - if root is None: - return root - # 循环访问左子节点,直到叶节点时为最小节点,跳出 - while root.left is not None: - root = root.left - return root + tmp: TreeNode = cur.right + while tmp.left is not None: + tmp = tmp.left + # 递归删除节点 tmp + self.remove(tmp.val) + # 用 tmp 覆盖 cur + cur.val = tmp.val """Driver Code""" @@ -149,7 +141,7 @@ if __name__ == "__main__": print("\n查找到的节点对象为: {},节点值 = {}".format(node, node.val)) # 插入节点 - node = bst.insert(16) + bst.insert(16) print("\n插入节点 16 后,二叉树为\n") print_tree(bst.root) diff --git a/codes/swift/chapter_tree/avl_tree.swift b/codes/swift/chapter_tree/avl_tree.swift index 0fb41976..087b5975 100644 --- a/codes/swift/chapter_tree/avl_tree.swift +++ b/codes/swift/chapter_tree/avl_tree.swift @@ -90,9 +90,8 @@ class AVLTree { /* 插入节点 */ @discardableResult - func insert(val: Int) -> TreeNode? { + func insert(val: Int) { root = insertHelper(node: root, val: val) - return root } /* 递归插入节点(辅助方法) */ @@ -118,9 +117,8 @@ class AVLTree { /* 删除节点 */ @discardableResult - func remove(val: Int) -> TreeNode? { + func remove(val: Int) { root = removeHelper(node: root, val: val) - return root } /* 递归删除节点(辅助方法) */ @@ -147,7 +145,10 @@ class AVLTree { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - let temp = getInOrderNext(node: node?.right) + let temp = node?.right + while temp?.left != nil { + temp = temp?.left + } node?.right = removeHelper(node: node?.right, val: temp!.val) node?.val = temp!.val } @@ -159,19 +160,6 @@ class AVLTree { return node } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - private func getInOrderNext(node: TreeNode?) -> TreeNode? { - var node = node - if node == nil { - return node - } - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while node?.left != nil { - node = node?.left - } - return node - } - /* 查找节点 */ func search(val: Int) -> TreeNode? { var cur = root diff --git a/codes/swift/chapter_tree/binary_search_tree.swift b/codes/swift/chapter_tree/binary_search_tree.swift index 5cb4b134..3ea129a1 100644 --- a/codes/swift/chapter_tree/binary_search_tree.swift +++ b/codes/swift/chapter_tree/binary_search_tree.swift @@ -57,10 +57,10 @@ class BinarySearchTree { } /* 插入节点 */ - func insert(num: Int) -> TreeNode? { + func insert(num: Int) { // 若树为空,直接提前返回 if root == nil { - return nil + return } var cur = root var pre: TreeNode? @@ -68,7 +68,7 @@ class BinarySearchTree { while cur != nil { // 找到重复节点,直接返回 if cur!.val == num { - return nil + return } pre = cur // 插入位置在 cur 的右子树中 @@ -87,15 +87,14 @@ class BinarySearchTree { } else { pre?.left = node } - return node } /* 删除节点 */ @discardableResult - func remove(num: Int) -> TreeNode? { + func remove(num: Int) { // 若树为空,直接提前返回 if root == nil { - return nil + return } var cur = root var pre: TreeNode? @@ -117,7 +116,7 @@ class BinarySearchTree { } // 若无待删除节点,则直接返回 if cur == nil { - return nil + return } // 子节点数量 = 0 or 1 if cur?.left == nil || cur?.right == nil { @@ -133,27 +132,15 @@ class BinarySearchTree { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - let nex = getInOrderNext(root: cur?.right) - let tmp = nex!.val - // 递归删除节点 nex - remove(num: nex!.val) - // 将 nex 的值复制给 cur - cur?.val = tmp + let tmp = cur?.right + while tmp?.left != nil { + tmp = tmp?.left + } + // 递归删除节点 tmp + remove(num: tmp!.val) + // 用 tmp 覆盖 cur + cur?.val = tmp!.val } - return cur - } - - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - func getInOrderNext(root: TreeNode?) -> TreeNode? { - var root = root - if root == nil { - return root - } - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while root?.left != nil { - root = root?.left - } - return root } } @@ -172,7 +159,7 @@ enum _BinarySearchTree { print("\n查找到的节点对象为 \(node!),节点值 = \(node!.val)") /* 插入节点 */ - node = bst.insert(num: 16) + bst.insert(num: 16) print("\n插入节点 16 后,二叉树为\n") PrintUtil.printTree(root: bst.getRoot()) diff --git a/codes/typescript/chapter_tree/avl_tree.ts b/codes/typescript/chapter_tree/avl_tree.ts index 7e5951c5..c217491c 100644 --- a/codes/typescript/chapter_tree/avl_tree.ts +++ b/codes/typescript/chapter_tree/avl_tree.ts @@ -94,9 +94,8 @@ class AVLTree { } /* 插入节点 */ - insert(val: number): TreeNode { + insert(val: number): void { this.root = this.insertHelper(this.root, val); - return this.root; } /* 递归插入节点(辅助方法) */ @@ -118,9 +117,8 @@ class AVLTree { } /* 删除节点 */ - remove(val: number): TreeNode { + remove(val: number): void { this.root = this.removeHelper(this.root, val); - return this.root; } /* 递归删除节点(辅助方法) */ @@ -143,7 +141,10 @@ class AVLTree { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - const temp = this.getInOrderNext(node.right); + let temp = node.right; + while (temp.left !== null) { + temp = temp.left; + } node.right = this.removeHelper(node.right, temp.val); node.val = temp.val; } @@ -155,16 +156,6 @@ class AVLTree { return node; } - /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ - private getInOrderNext(node: TreeNode): TreeNode { - if (node === null) return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node.left !== null) { - node = node.left; - } - return node; - } - /* 查找节点 */ search(val: number): TreeNode { let cur = this.root; diff --git a/codes/typescript/chapter_tree/binary_search_tree.ts b/codes/typescript/chapter_tree/binary_search_tree.ts index 51508a86..fa40a0ca 100644 --- a/codes/typescript/chapter_tree/binary_search_tree.ts +++ b/codes/typescript/chapter_tree/binary_search_tree.ts @@ -52,17 +52,17 @@ function search(num: number): TreeNode | null { } /* 插入节点 */ -function insert(num: number): TreeNode | null { +function insert(num: number): void { // 若树为空,直接提前返回 if (root === null) { - return null; + return; } let cur = root, pre: TreeNode | null = null; // 循环查找,越过叶节点后跳出 while (cur !== null) { if (cur.val === num) { - return null; // 找到重复节点,直接返回 + return; // 找到重复节点,直接返回 } pre = cur; if (cur.val < num) { @@ -78,14 +78,13 @@ function insert(num: number): TreeNode | null { } else { pre!.left = node; } - return node; } /* 删除节点 */ -function remove(num: number): TreeNode | null { +function remove(num: number): void { // 若树为空,直接提前返回 if (root === null) { - return null; + return; } let cur = root, pre: TreeNode | null = null; @@ -104,7 +103,7 @@ function remove(num: number): TreeNode | null { } // 若无待删除节点,则直接返回 if (cur === null) { - return null; + return; } // 子节点数量 = 0 or 1 if (cur.left === null || cur.right === null) { @@ -120,26 +119,15 @@ function remove(num: number): TreeNode | null { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - let next = getInOrderNext(cur.right); - let tmp = next!.val; - // 递归删除节点 nex - remove(next!.val); - // 将 nex 的值复制给 cur - cur.val = tmp; + let tmp = cur.right; + while (tmp.left !== null) { + tmp = tmp.left; + } + // 递归删除节点 tmp + remove(tmp!.val); + // 用 tmp 覆盖 cur + cur.val = tmp.val; } - return cur; -} - -/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ -function getInOrderNext(root: TreeNode | null): TreeNode | null { - if (root === null) { - return null; - } - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (root.left !== null) { - root = root.left; - } - return root; } /* Driver Code */ @@ -154,7 +142,7 @@ let node = search(7); console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + node!.val); /* 插入节点 */ -node = insert(16); +insert(16); console.log('\n插入节点 16 后,二叉树为\n'); printTree(getRoot()); diff --git a/codes/zig/chapter_tree/avl_tree.zig b/codes/zig/chapter_tree/avl_tree.zig index b6647207..0e6207d4 100644 --- a/codes/zig/chapter_tree/avl_tree.zig +++ b/codes/zig/chapter_tree/avl_tree.zig @@ -108,9 +108,8 @@ pub fn AVLTree(comptime T: type) type { } // 插入节点 - fn insert(self: *Self, val: T) !?*inc.TreeNode(T) { + fn insert(self: *Self, val: T) void { self.root = try self.insertHelper(self.root, val); - return self.root; } // 递归插入节点(辅助方法) @@ -137,9 +136,8 @@ pub fn AVLTree(comptime T: type) type { } // 删除节点 - fn remove(self: *Self, val: T) ?*inc.TreeNode(T) { + fn remove(self: *Self, val: T) void { self.root = self.removeHelper(self.root, val); - return self.root; } // 递归删除节点(辅助方法) @@ -163,30 +161,21 @@ pub fn AVLTree(comptime T: type) type { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - var temp = self.getInOrderNext(node.?.right); + var temp = node.?.right; + while (temp.?.left != null) { + temp = temp.?.left; + } node.?.right = self.removeHelper(node.?.right, temp.?.val); node.?.val = temp.?.val; } } - self.updateHeight(node); // 更新节点高度 + self.updateHeight(node); // 更新节点高度 // 2. 执行旋转操作,使该子树重新恢复平衡 node = self.rotate(node); // 返回子树的根节点 return node; } - // 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) - fn getInOrderNext(self: *Self, node_: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) { - _ = self; - var node = node_; - if (node == null) return node; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node.?.left != null) { - node = node.?.left; - } - return node; - } - // 查找节点 fn search(self: *Self, val: T) ?*inc.TreeNode(T) { var cur = self.root; diff --git a/codes/zig/chapter_tree/binary_search_tree.zig b/codes/zig/chapter_tree/binary_search_tree.zig index c94cdb6c..ca62cd69 100644 --- a/codes/zig/chapter_tree/binary_search_tree.zig +++ b/codes/zig/chapter_tree/binary_search_tree.zig @@ -69,15 +69,15 @@ pub fn BinarySearchTree(comptime T: type) type { } // 插入节点 - fn insert(self: *Self, num: T) !?*inc.TreeNode(T) { + fn insert(self: *Self, num: T) !void { // 若树为空,直接提前返回 - if (self.root == null) return null; + if (self.root == null) return; var cur = self.root; var pre: ?*inc.TreeNode(T) = null; // 循环查找,越过叶节点后跳出 while (cur != null) { // 找到重复节点,直接返回 - if (cur.?.val == num) return null; + if (cur.?.val == num) return; pre = cur; // 插入位置在 cur 的右子树中 if (cur.?.val < num) { @@ -95,13 +95,12 @@ pub fn BinarySearchTree(comptime T: type) type { } else { pre.?.left = node; } - return node; } // 删除节点 - fn remove(self: *Self, num: T) ?*inc.TreeNode(T) { + fn remove(self: *Self, num: T) !void { // 若树为空,直接提前返回 - if (self.root == null) return null; + if (self.root == null) return; var cur = self.root; var pre: ?*inc.TreeNode(T) = null; // 循环查找,越过叶节点后跳出 @@ -118,7 +117,7 @@ pub fn BinarySearchTree(comptime T: type) type { } } // 若无待删除节点,则直接返回 - if (cur == null) return null; + if (cur == null) return; // 子节点数量 = 0 or 1 if (cur.?.left == null or cur.?.right == null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 @@ -132,26 +131,16 @@ pub fn BinarySearchTree(comptime T: type) type { // 子节点数量 = 2 } else { // 获取中序遍历中 cur 的下一个节点 - var nex = self.getInOrderNext(cur.?.right); - var tmp = nex.?.val; - // 递归删除节点 nex - _ = self.remove(nex.?.val); - // 将 nex 的值复制给 cur - cur.?.val = tmp; + var tmp = cur.?.right; + while (tmp.?.left != null) { + tmp = tmp.?.left; + } + var tmpVal = tmp.?.val; + // 递归删除节点 tmp + _ = self.remove(tmp.?.val); + // 用 tmp 覆盖 cur + cur.?.val = tmpVal; } - return cur; - } - - // 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) - fn getInOrderNext(self: *Self, node: ?*inc.TreeNode(T)) ?*inc.TreeNode(T) { - _ = self; - var node_tmp = node; - if (node_tmp == null) return null; - // 循环访问左子节点,直到叶节点时为最小节点,跳出 - while (node_tmp.?.left != null) { - node_tmp = node_tmp.?.left; - } - return node_tmp; } }; } diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index 9fa5cb5d..affe026a 100755 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -180,9 +180,9 @@ 当待删除节点的子节点数量 $= 2$ 时,删除操作分为三步: -1. 找到待删除节点在“中序遍历序列”中的下一个节点,记为 nex; -2. 在树中递归删除节点 `nex` ; -3. 使用 `nex` 替换待删除节点; +1. 找到待删除节点在“中序遍历序列”中的下一个节点,记为 `tmp` ; +2. 在树中递归删除节点 `tmp` ; +3. 用 `tmp` 的值覆盖待删除节点的值; === "<1>" ![bst_remove_case3_step1](binary_search_tree.assets/bst_remove_case3_step1.png)