From 410c5d6b6270dd58fac638194e56f879fec512eb Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Mon, 2 Jan 2023 19:53:55 +0800 Subject: [PATCH] Free memory after removing a node from a LinkedList or TreeNode. --- .../linked_list.cpp | 2 + .../linkedlist_queue.cpp | 3 + .../linkedlist_stack.cpp | 3 + codes/cpp/chapter_tree/binary_search_tree.cpp | 8 ++- codes/cpp/chapter_tree/binary_tree.cpp | 1 + codes/csharp/chapter_tree/avl_tree.cs | 6 +- .../csharp/chapter_tree/binary_search_tree.cs | 6 +- codes/go/chapter_tree/binary_search_tree.go | 21 ++----- .../chapter_tree/binary_search_tree_test.go | 17 +++--- codes/java/chapter_tree/avl_tree.java | 6 +- .../java/chapter_tree/binary_search_tree.java | 6 +- .../chapter_tree/binary_search_tree.js | 6 +- codes/python/chapter_tree/avl_tree.py | 6 +- .../python/chapter_tree/binary_search_tree.py | 7 +-- .../chapter_tree/binary_search_tree.ts | 6 +- .../linked_list.md | 2 + docs/chapter_stack_and_queue/queue.md | 3 + docs/chapter_stack_and_queue/stack.md | 3 + docs/chapter_tree/avl_tree.md | 37 +----------- docs/chapter_tree/binary_search_tree.md | 60 +++---------------- 20 files changed, 69 insertions(+), 140 deletions(-) diff --git a/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp b/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp index 46116d291..4cf049204 100644 --- a/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp @@ -21,6 +21,8 @@ void remove(ListNode* n0) { ListNode* P = n0->next; ListNode* n1 = P->next; n0->next = n1; + // 释放内存 + delete P; } /* 访问链表中索引为 index 的结点 */ diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp index 17625322d..dcaac225f 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp @@ -50,7 +50,10 @@ public: int poll() { int num = peek(); // 删除头结点 + ListNode *tmp = front; front = front->next; + // 释放内存 + delete tmp; queSize--; return num; } diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp index 1bb7c2a3c..312b75135 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp @@ -39,7 +39,10 @@ public: /* 出栈 */ int pop() { int num = top(); + ListNode *tmp = stackTop; stackTop = stackTop->next; + // 释放内存 + delete tmp; stkSize--; return num; } diff --git a/codes/cpp/chapter_tree/binary_search_tree.cpp b/codes/cpp/chapter_tree/binary_search_tree.cpp index 246bdbaa1..c7f8734da 100644 --- a/codes/cpp/chapter_tree/binary_search_tree.cpp +++ b/codes/cpp/chapter_tree/binary_search_tree.cpp @@ -96,11 +96,13 @@ public: // 删除结点 cur if (pre->left == cur) pre->left = child; else pre->right = child; + // 释放内存 + delete cur; } // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - TreeNode* nex = min(cur->right); + TreeNode* nex = getInOrderNext(cur->right); int tmp = nex->val; // 递归删除结点 nex remove(nex->val); @@ -110,8 +112,8 @@ public: return cur; } - /* 获取最小结点 */ - TreeNode* min(TreeNode* root) { + /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ + TreeNode* getInOrderNext(TreeNode* root) { if (root == nullptr) return root; // 循环访问左子结点,直到叶结点时为最小结点,跳出 while (root->left != nullptr) { diff --git a/codes/cpp/chapter_tree/binary_tree.cpp b/codes/cpp/chapter_tree/binary_tree.cpp index 3258d9cfc..fb00431eb 100644 --- a/codes/cpp/chapter_tree/binary_tree.cpp +++ b/codes/cpp/chapter_tree/binary_tree.cpp @@ -33,6 +33,7 @@ int main() { PrintUtil::printTree(n1); // 删除结点 P n1->left = n2; + delete P; // 释放内存 cout << endl << "删除结点 P 后\n" << endl; PrintUtil::printTree(n1); diff --git a/codes/csharp/chapter_tree/avl_tree.cs b/codes/csharp/chapter_tree/avl_tree.cs index 99ec17f63..6bcb559b7 100644 --- a/codes/csharp/chapter_tree/avl_tree.cs +++ b/codes/csharp/chapter_tree/avl_tree.cs @@ -162,7 +162,7 @@ namespace hello_algo.chapter_tree else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - TreeNode? temp = minNode(node.right); + TreeNode? temp = getInOrderNext(node.right); node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -174,8 +174,8 @@ namespace hello_algo.chapter_tree return node; } - /* 获取最小结点 */ - private TreeNode? minNode(TreeNode? node) + /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ + private TreeNode? getInOrderNext(TreeNode? node) { if (node == null) return node; // 循环访问左子结点,直到叶结点时为最小结点,跳出 diff --git a/codes/csharp/chapter_tree/binary_search_tree.cs b/codes/csharp/chapter_tree/binary_search_tree.cs index 8224317df..5164cf780 100644 --- a/codes/csharp/chapter_tree/binary_search_tree.cs +++ b/codes/csharp/chapter_tree/binary_search_tree.cs @@ -125,7 +125,7 @@ namespace hello_algo.chapter_tree else { // 获取中序遍历中 cur 的下一个结点 - TreeNode? nex = min(cur.right); + TreeNode? nex = getInOrderNext(cur.right); if (nex != null) { int tmp = nex.val; @@ -138,8 +138,8 @@ namespace hello_algo.chapter_tree return cur; } - /* 获取最小结点 */ - private TreeNode? min(TreeNode? root) + /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ + private TreeNode? getInOrderNext(TreeNode? root) { if (root == null) return root; // 循环访问左子结点,直到叶结点时为最小结点,跳出 diff --git a/codes/go/chapter_tree/binary_search_tree.go b/codes/go/chapter_tree/binary_search_tree.go index 2af2e7be0..c8fc5d62c 100644 --- a/codes/go/chapter_tree/binary_search_tree.go +++ b/codes/go/chapter_tree/binary_search_tree.go @@ -23,13 +23,13 @@ func NewBinarySearchTree(nums []int) *BinarySearchTree { } } -// GetRoot Get the root node of binary search tree +/* 获取根结点 */ func (bst *BinarySearchTree) GetRoot() *TreeNode { return bst.root } -// GetMin Get node with the min value -func (bst *BinarySearchTree) GetMin(node *TreeNode) *TreeNode { +/* 获取中序遍历的下一个结点 */ +func (bst *BinarySearchTree) GetInOrderNext(node *TreeNode) *TreeNode { if node == nil { return node } @@ -40,19 +40,6 @@ func (bst *BinarySearchTree) GetMin(node *TreeNode) *TreeNode { return node } -// GetInorderNext Get node inorder next -func (bst *BinarySearchTree) GetInorderNext(node *TreeNode) *TreeNode { - if node == nil || node.Right == nil { - return node - } - node = node.Right - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - for node.Left != nil { - node = node.Left - } - return node -} - /* 查找结点 */ func (bst *BinarySearchTree) Search(num int) *TreeNode { node := bst.root @@ -149,7 +136,7 @@ func (bst *BinarySearchTree) Remove(num int) *TreeNode { // 子结点数为 2 } else { // 获取中序遍历中待删除结点 cur 的下一个结点 - next := bst.GetInorderNext(cur) + next := bst.GetInOrderNext(cur) temp := next.Val // 递归删除结点 next bst.Remove(next.Val) diff --git a/codes/go/chapter_tree/binary_search_tree_test.go b/codes/go/chapter_tree/binary_search_tree_test.go index 0d0369a78..cdf7d8d48 100644 --- a/codes/go/chapter_tree/binary_search_tree_test.go +++ b/codes/go/chapter_tree/binary_search_tree_test.go @@ -12,33 +12,30 @@ import ( func TestBinarySearchTree(t *testing.T) { nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} bst := NewBinarySearchTree(nums) - fmt.Println("初始化的二叉树为:") + fmt.Println("\n初始化的二叉树为:") bst.Print() // 获取根结点 node := bst.GetRoot() - fmt.Println("二叉树的根结点为:", node.Val) - // 获取最小的结点 - node = bst.GetMin(bst.GetRoot()) - fmt.Println("二叉树的最小结点为:", node.Val) + fmt.Println("\n二叉树的根结点为:", node.Val) // 查找结点 node = bst.Search(5) - fmt.Println("查找到的结点对象为", node, ",结点值 =", node.Val) + fmt.Println("\n查找到的结点对象为", node, ",结点值 =", node.Val) // 插入结点 node = bst.Insert(16) - fmt.Println("插入结点后 16 的二叉树为:") + fmt.Println("\n插入结点后 16 的二叉树为:") bst.Print() // 删除结点 bst.Remove(1) - fmt.Println("删除结点 1 后的二叉树为:") + fmt.Println("\n删除结点 1 后的二叉树为:") bst.Print() bst.Remove(2) - fmt.Println("删除结点 2 后的二叉树为:") + fmt.Println("\n删除结点 2 后的二叉树为:") bst.Print() bst.Remove(4) - fmt.Println("删除结点 4 后的二叉树为:") + fmt.Println("\n删除结点 4 后的二叉树为:") bst.Print() } diff --git a/codes/java/chapter_tree/avl_tree.java b/codes/java/chapter_tree/avl_tree.java index 48be762e9..2f731b7e4 100644 --- a/codes/java/chapter_tree/avl_tree.java +++ b/codes/java/chapter_tree/avl_tree.java @@ -138,7 +138,7 @@ class AVLTree { node = child; } else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - TreeNode temp = minNode(node.right); + TreeNode temp = getInOrderNext(node.right); node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -150,8 +150,8 @@ class AVLTree { return node; } - /* 获取最小结点 */ - private TreeNode minNode(TreeNode node) { + /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ + private TreeNode getInOrderNext(TreeNode node) { if (node == null) return node; // 循环访问左子结点,直到叶结点时为最小结点,跳出 while (node.left != null) { diff --git a/codes/java/chapter_tree/binary_search_tree.java b/codes/java/chapter_tree/binary_search_tree.java index 0770c567d..4a7c53dba 100644 --- a/codes/java/chapter_tree/binary_search_tree.java +++ b/codes/java/chapter_tree/binary_search_tree.java @@ -101,7 +101,7 @@ class BinarySearchTree { // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - TreeNode nex = min(cur.right); + TreeNode nex = getInOrderNext(cur.right); int tmp = nex.val; // 递归删除结点 nex remove(nex.val); @@ -111,8 +111,8 @@ class BinarySearchTree { return cur; } - /* 获取最小结点 */ - public TreeNode min(TreeNode root) { + /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ + public TreeNode getInOrderNext(TreeNode root) { if (root == null) return root; // 循环访问左子结点,直到叶结点时为最小结点,跳出 while (root.left != null) { diff --git a/codes/javascript/chapter_tree/binary_search_tree.js b/codes/javascript/chapter_tree/binary_search_tree.js index 1e0d92738..c00d8bea8 100644 --- a/codes/javascript/chapter_tree/binary_search_tree.js +++ b/codes/javascript/chapter_tree/binary_search_tree.js @@ -98,7 +98,7 @@ function remove(num) { // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - let nex = min(cur.right); + let nex = getInOrderNext(cur.right); let tmp = nex.val; // 递归删除结点 nex remove(nex.val); @@ -108,8 +108,8 @@ function remove(num) { return cur; } -/* 获取最小结点 */ -function min(root) { +/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ +function getInOrderNext(root) { if (root === null) return root; // 循环访问左子结点,直到叶结点时为最小结点,跳出 while (root.left !== null) { diff --git a/codes/python/chapter_tree/avl_tree.py b/codes/python/chapter_tree/avl_tree.py index d0ff48cba..04218e46a 100644 --- a/codes/python/chapter_tree/avl_tree.py +++ b/codes/python/chapter_tree/avl_tree.py @@ -132,7 +132,7 @@ class AVLTree: else: node = child else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - temp = self.__min_node(node.right) + temp = self.__get_inorder_next(node.right) node.right = self.__remove_helper(node.right, temp.val) node.val = temp.val # 更新结点高度 @@ -140,8 +140,8 @@ class AVLTree: # 2. 执行旋转操作,使该子树重新恢复平衡 return self.__rotate(node) - """ 获取最小结点 """ - def __min_node(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: + """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ + def __get_inorder_next(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if node is None: return None # 循环访问左子结点,直到叶结点时为最小结点,跳出 diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index 23e341854..db52d57bd 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -117,7 +117,7 @@ class BinarySearchTree: # 子结点数量 = 2 else: # 获取中序遍历中 cur 的下一个结点 - nex = self.min(cur.right) + nex = self.get_inorder_next(cur.right) tmp = nex.val # 递归删除结点 nex self.remove(nex.val) @@ -125,11 +125,10 @@ class BinarySearchTree: cur.val = tmp return cur - """ 获取最小结点 """ - def min(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: + """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ + def get_inorder_next(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: if root is None: return root - # 循环访问左子结点,直到叶结点时为最小结点,跳出 while root.left is not None: root = root.left diff --git a/codes/typescript/chapter_tree/binary_search_tree.ts b/codes/typescript/chapter_tree/binary_search_tree.ts index 6dad83421..a99e6ba26 100644 --- a/codes/typescript/chapter_tree/binary_search_tree.ts +++ b/codes/typescript/chapter_tree/binary_search_tree.ts @@ -120,7 +120,7 @@ function remove(num: number): TreeNode | null { // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - let next = min(cur.right); + let next = getInOrderNext(cur.right); let tmp = next!.val; // 递归删除结点 nex remove(next!.val); @@ -130,8 +130,8 @@ function remove(num: number): TreeNode | null { return cur; } -/* 获取最小结点 */ -function min(root: TreeNode | null): TreeNode | null { +/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ +function getInOrderNext(root: TreeNode | null): TreeNode | null { if (root === null) { return null; } diff --git a/docs/chapter_array_and_linkedlist/linked_list.md b/docs/chapter_array_and_linkedlist/linked_list.md index a55d68028..5b6888c06 100644 --- a/docs/chapter_array_and_linkedlist/linked_list.md +++ b/docs/chapter_array_and_linkedlist/linked_list.md @@ -293,6 +293,8 @@ comments: true ListNode* P = n0->next; ListNode* n1 = P->next; n0->next = n1; + // 释放内存 + delete P; } ``` diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index 3c5c0528d..cc815b3ab 100644 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -331,7 +331,10 @@ comments: true int poll() { int num = peek(); // 删除头结点 + ListNode *tmp = front; front = front->next; + // 释放内存 + delete tmp; queSize--; return num; } diff --git a/docs/chapter_stack_and_queue/stack.md b/docs/chapter_stack_and_queue/stack.md index b0d577bce..7e35fddbd 100644 --- a/docs/chapter_stack_and_queue/stack.md +++ b/docs/chapter_stack_and_queue/stack.md @@ -311,7 +311,10 @@ comments: true /* 出栈 */ int pop() { int num = top(); + ListNode *tmp = stackTop; stackTop = stackTop->next; + // 释放内存 + delete tmp; stkSize--; return num; } diff --git a/docs/chapter_tree/avl_tree.md b/docs/chapter_tree/avl_tree.md index e9a656bed..45308fa6f 100644 --- a/docs/chapter_tree/avl_tree.md +++ b/docs/chapter_tree/avl_tree.md @@ -772,7 +772,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 node = child; } else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - TreeNode temp = minNode(node.right); + TreeNode temp = getInOrderNext(node.right); node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -783,16 +783,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 // 返回子树的根节点 return node; } - - /* 获取最小结点 */ - TreeNode minNode(TreeNode node) { - if (node == null) return node; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (node.left != null) { - node = node.left; - } - return node; - } ``` === "C++" @@ -828,22 +818,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 else: node = child else: # 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - temp = self.min_node(node.right) + temp = self.__get_inorder_next(node.right) node.right = self.__remove_helper(node.right, temp.val) node.val = temp.val # 更新结点高度 self.__update_height(node) # 2. 执行旋转操作,使该子树重新恢复平衡 return self.__rotate(node) - - """ 获取最小结点 """ - def min_node(self, node: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: - if node is None: - return None - # 循环访问左子结点,直到叶结点时为最小结点,跳出 - while node.left is not None: - node = node.left - return node ``` === "Go" @@ -904,7 +885,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - TreeNode? temp = minNode(node.right); + TreeNode? temp = getInOrderNext(node.right); node.right = removeHelper(node.right, temp.val); node.val = temp.val; } @@ -915,18 +896,6 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 // 返回子树的根节点 return node; } - - /* 获取最小结点 */ - private TreeNode? minNode(TreeNode? node) - { - if (node == null) return node; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (node.left != null) - { - node = node.left; - } - return node; - } ``` ### 查找结点 diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index 629c051f1..cc7c2f51c 100644 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -445,19 +445,15 @@ comments: true 3. 使用 `nex` 替换待删除结点; === "Step 1" - ![bst_remove_case3_1](binary_search_tree.assets/bst_remove_case3_1.png) === "Step 2" - ![bst_remove_case3_2](binary_search_tree.assets/bst_remove_case3_2.png) === "Step 3" - ![bst_remove_case3_3](binary_search_tree.assets/bst_remove_case3_3.png) === "Step 4" - ![bst_remove_case3_4](binary_search_tree.assets/bst_remove_case3_4.png) 删除结点操作也使用 $O(\log n)$ 时间,其中查找待删除结点 $O(\log n)$ ,获取中序遍历后继结点 $O(\log n)$ 。 @@ -489,11 +485,13 @@ comments: true // 删除结点 cur if (pre.left == cur) pre.left = child; else pre.right = child; + // 释放内存 + delete cur; } // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - TreeNode nex = min(cur.right); + TreeNode nex = getInOrderNext(cur.right); int tmp = nex.val; // 递归删除结点 nex remove(nex.val); @@ -502,15 +500,6 @@ comments: true } return cur; } - /* 获取最小结点 */ - TreeNode min(TreeNode root) { - if (root == null) return root; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (root.left != null) { - root = root.left; - } - return root; - } ``` === "C++" @@ -544,7 +533,7 @@ comments: true // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - TreeNode* nex = min(cur->right); + TreeNode* nex = getInOrderNext(cur->right); int tmp = nex->val; // 递归删除结点 nex remove(nex->val); @@ -553,15 +542,6 @@ comments: true } return cur; } - /* 获取最小结点 */ - TreeNode* min(TreeNode* root) { - if (root == nullptr) return root; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (root->left != nullptr) { - root = root->left; - } - return root; - } ``` === "Python" @@ -604,23 +584,13 @@ comments: true # 子结点数量 = 2 else: # 获取中序遍历中 cur 的下一个结点 - nex = self.min(cur.right) + nex = self.get_inorder_next(cur.right) tmp = nex.val # 递归删除结点 nex self.remove(nex.val) # 将 nex 的值复制给 cur cur.val = tmp return cur - - """ 获取最小结点 """ - def min(self, root: typing.Optional[TreeNode]) -> typing.Optional[TreeNode]: - if root is None: - return root - - # 循环访问左子结点,直到叶结点时为最小结点,跳出 - while root.left is not None: - root = root.left - return root ``` === "Go" @@ -671,7 +641,7 @@ comments: true // 子结点数为 2 } else { // 获取中序遍历中待删除结点 cur 的下一个结点 - next := bst.GetInorderNext(cur) + next := bst.GetInOrderNext(cur) temp := next.Val // 递归删除结点 next bst.Remove(next.Val) @@ -713,7 +683,7 @@ comments: true // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - let nex = min(cur.right); + let nex = getInOrderNext(cur.right); let tmp = nex.val; // 递归删除结点 nex remove(nex.val); @@ -766,7 +736,7 @@ comments: true // 子结点数量 = 2 else { // 获取中序遍历中 cur 的下一个结点 - let next = min(cur.right); + let next = getInOrderNext(cur.right); let tmp = next!.val; // 递归删除结点 nex remove(next!.val); @@ -824,7 +794,7 @@ comments: true else { // 获取中序遍历中 cur 的下一个结点 - TreeNode? nex = min(cur.right); + TreeNode? nex = getInOrderNext(cur.right); if (nex != null) { int tmp = nex.val; @@ -836,18 +806,6 @@ comments: true } return cur; } - - /* 获取最小结点 */ - TreeNode? min(TreeNode? root) - { - if (root == null) return root; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (root.left != null) - { - root = root.left; - } - return root; - } ``` ## 二叉搜索树的优势