From bb657f95179e9d577e65035332200e5826838d6f Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Sat, 14 Jan 2023 19:52:11 +0800 Subject: [PATCH] Add destructors to the C++ codes. --- .../cpp/chapter_array_and_linkedlist/array.cpp | 11 +++++++---- .../linked_list.cpp | 3 +++ .../chapter_array_and_linkedlist/my_list.cpp | 18 +++++++++++++----- .../leetcode_two_sum.cpp | 4 ++++ .../space_complexity.cpp | 9 ++++++--- .../chapter_stack_and_queue/array_queue.cpp | 7 +++++++ .../chapter_stack_and_queue/array_stack.cpp | 3 +++ .../linkedlist_queue.cpp | 8 ++++++++ .../linkedlist_stack.cpp | 7 +++++++ codes/cpp/chapter_tree/binary_search_tree.cpp | 7 +++++++ codes/cpp/chapter_tree/binary_tree.cpp | 3 +++ codes/cpp/include/ListNode.hpp | 15 +++++++++++++++ codes/cpp/include/TreeNode.hpp | 13 +++++++++++++ docs/chapter_array_and_linkedlist/array.md | 2 ++ docs/chapter_array_and_linkedlist/list.md | 15 ++++++++++----- .../space_complexity.md | 6 +++--- docs/chapter_stack_and_queue/queue.md | 7 +++++++ docs/chapter_stack_and_queue/stack.md | 3 +++ docs/chapter_tree/binary_search_tree.md | 4 ---- 19 files changed, 121 insertions(+), 24 deletions(-) diff --git a/codes/cpp/chapter_array_and_linkedlist/array.cpp b/codes/cpp/chapter_array_and_linkedlist/array.cpp index 6cf4919be..149a1ca24 100644 --- a/codes/cpp/chapter_array_and_linkedlist/array.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/array.cpp @@ -23,6 +23,8 @@ int* extend(int* nums, int size, int enlarge) { for (int i = 0; i < size; i++) { res[i] = nums[i]; } + // 释放内存 + delete[] nums; // 返回扩展后的新数组 return res; } @@ -82,10 +84,7 @@ int main() { /* 长度扩展 */ int enlarge = 3; - int* res = extend(nums, size, enlarge); - int* temp = nums; - nums = res; - delete[] temp; + nums = extend(nums, size, enlarge); size += enlarge; cout << "将数组长度扩展至 8 ,得到 nums = "; PrintUtil::printArray(nums, size); @@ -107,5 +106,9 @@ int main() { int index = find(nums, size, 3); cout << "在 nums 中查找元素 3 ,得到索引 = " << index << endl; + // 释放内存 + delete[] arr; + delete[] nums; + return 0; } diff --git a/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp b/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp index 5e976a89a..3e457891c 100644 --- a/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp @@ -83,5 +83,8 @@ int main() { int index = find(n0, 2); cout << "链表中值为 2 的结点的索引 = " << index << endl; + // 释放内存 + freeMemoryLinkedList(n0); + return 0; } diff --git a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp index 0b550475e..7349e6f10 100644 --- a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp @@ -20,6 +20,11 @@ public: nums = new int[numsCapacity]; } + /* 析构函数 */ + ~MyList() { + delete[] nums; + } + /* 获取列表长度(即当前元素数量)*/ int size() { return numsSize; @@ -90,14 +95,14 @@ public: void extendCapacity() { // 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组 int newCapacity = capacity() * extendRatio; - int* extend = new int[newCapacity]; + int* tmp = nums; + nums = new int[newCapacity]; // 将原数组中的所有元素复制到新数组 for (int i = 0; i < size(); i++) { - extend[i] = nums[i]; + nums[i] = tmp[i]; } - int* temp = nums; - nums = extend; - delete[] temp; + // 释放内存 + delete[] tmp; numsCapacity = newCapacity; } @@ -160,5 +165,8 @@ int main() { PrintUtil::printVector(vec); cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl; + // 释放内存 + delete list; + return 0; } diff --git a/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp b/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp index dd561d544..f68f242b9 100644 --- a/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp +++ b/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp @@ -56,5 +56,9 @@ int main() { cout << "方法二 res = "; PrintUtil::printVector(res); + // 释放内存 + delete slt1; + delete slt2; + return 0; } diff --git a/codes/cpp/chapter_computational_complexity/space_complexity.cpp b/codes/cpp/chapter_computational_complexity/space_complexity.cpp index 6352b9d47..4a0e79ec1 100644 --- a/codes/cpp/chapter_computational_complexity/space_complexity.cpp +++ b/codes/cpp/chapter_computational_complexity/space_complexity.cpp @@ -18,7 +18,7 @@ void constant(int n) { const int a = 0; int b = 0; vector nums(10000); - ListNode* node = new ListNode(0); + ListNode node(0); // 循环中的变量占用 O(1) 空间 for (int i = 0; i < n; i++) { int c = 0; @@ -34,9 +34,9 @@ void linear(int n) { // 长度为 n 的数组占用 O(n) 空间 vector nums(n); // 长度为 n 的列表占用 O(n) 空间 - vector nodes; + vector nodes; for (int i = 0; i < n; i++) { - nodes.push_back(new ListNode(i)); + nodes.push_back(ListNode(i)); } // 长度为 n 的哈希表占用 O(n) 空间 unordered_map map; @@ -98,5 +98,8 @@ int main() { TreeNode* root = buildTree(n); PrintUtil::printTree(root); + // 释放内存 + freeMemoryTree(root); + return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/array_queue.cpp b/codes/cpp/chapter_stack_and_queue/array_queue.cpp index de5e780f6..56b086e7d 100644 --- a/codes/cpp/chapter_stack_and_queue/array_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/array_queue.cpp @@ -21,6 +21,10 @@ public: nums = new int[capacity]; } + ~ArrayQueue() { + delete[] nums; + } + /* 获取队列的容量 */ int capacity() { return cap; @@ -117,5 +121,8 @@ int main() { PrintUtil::printVector(queue->toVector()); } + // 释放内存 + delete queue; + return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/array_stack.cpp b/codes/cpp/chapter_stack_and_queue/array_stack.cpp index e6159e8cf..7f705d7e4 100644 --- a/codes/cpp/chapter_stack_and_queue/array_stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/array_stack.cpp @@ -78,5 +78,8 @@ int main() { bool empty = stack->empty(); cout << "栈是否为空 = " << empty << endl; + // 释放内存 + delete stack; + return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp index ae22740d6..6c830ff8e 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_queue.cpp @@ -19,6 +19,11 @@ public: queSize = 0; } + ~LinkedListQueue() { + delete front; + delete rear; + } + /* 获取队列的长度 */ int size() { return queSize; @@ -108,5 +113,8 @@ int main() { bool empty = queue->empty(); cout << "队列是否为空 = " << empty << endl; + // 释放内存 + delete queue; + return 0; } diff --git a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp index 495f2660f..7b25a9e45 100644 --- a/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp +++ b/codes/cpp/chapter_stack_and_queue/linkedlist_stack.cpp @@ -18,6 +18,10 @@ public: stkSize = 0; } + ~LinkedListStack() { + freeMemoryLinkedList(stackTop); + } + /* 获取栈的长度 */ int size() { return stkSize; @@ -97,5 +101,8 @@ int main() { bool empty = stack->empty(); cout << "栈是否为空 = " << empty << endl; + // 释放内存 + delete stack; + return 0; } diff --git a/codes/cpp/chapter_tree/binary_search_tree.cpp b/codes/cpp/chapter_tree/binary_search_tree.cpp index 006d7d308..fbbed9e92 100644 --- a/codes/cpp/chapter_tree/binary_search_tree.cpp +++ b/codes/cpp/chapter_tree/binary_search_tree.cpp @@ -17,6 +17,10 @@ public: root = buildTree(nums, 0, nums.size() - 1); // 构建二叉搜索树 } + ~BinarySearchTree() { + freeMemoryTree(root); + } + /* 获取二叉树根结点 */ TreeNode* getRoot() { return root; @@ -152,5 +156,8 @@ int main() { cout << endl << "删除结点 4 后,二叉树为\n" << endl; PrintUtil::printTree(bst->getRoot()); + // 释放内存 + delete bst; + return 0; } diff --git a/codes/cpp/chapter_tree/binary_tree.cpp b/codes/cpp/chapter_tree/binary_tree.cpp index cd06778ad..f6a0a5d83 100644 --- a/codes/cpp/chapter_tree/binary_tree.cpp +++ b/codes/cpp/chapter_tree/binary_tree.cpp @@ -37,5 +37,8 @@ int main() { cout << endl << "删除结点 P 后\n" << endl; PrintUtil::printTree(n1); + // 释放内存 + freeMemoryTree(n1); + return 0; } diff --git a/codes/cpp/include/ListNode.hpp b/codes/cpp/include/ListNode.hpp index 9e6bd0692..7b1eb4134 100644 --- a/codes/cpp/include/ListNode.hpp +++ b/codes/cpp/include/ListNode.hpp @@ -48,3 +48,18 @@ ListNode* getListNode(ListNode *head, int val) { } return head; } + +/** + * @brief Free the memory allocated to a linked list + * + * @param cur + */ +void freeMemoryLinkedList(ListNode *cur) { + // 释放内存 + ListNode *pre; + while (cur != nullptr) { + pre = cur; + cur = cur->next; + delete pre; + } +} diff --git a/codes/cpp/include/TreeNode.hpp b/codes/cpp/include/TreeNode.hpp index 82f2ce981..505c40695 100644 --- a/codes/cpp/include/TreeNode.hpp +++ b/codes/cpp/include/TreeNode.hpp @@ -68,3 +68,16 @@ TreeNode *getTreeNode(TreeNode *root, int val) { TreeNode *right = getTreeNode(root->right, val); return left != nullptr ? left : right; } + +/** + * @brief Free the memory allocated to a tree + * + * @param root + */ +void freeMemoryTree(TreeNode *root) { + if (root == nullptr) return; + freeMemoryTree(root->left); + freeMemoryTree(root->right); + // 释放内存 + delete root; +} diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index 2251362d0..fcbdf9ab2 100644 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -245,6 +245,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex for (int i = 0; i < size; i++) { res[i] = nums[i]; } + // 释放内存 + delete[] nums; // 返回扩展后的新数组 return res; } diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index 1a47a0d13..e57d49875 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -748,6 +748,11 @@ comments: true nums = new int[numsCapacity]; } + /* 析构函数 */ + ~MyList() { + delete[] nums; + } + /* 获取列表长度(即当前元素数量)*/ int size() { return numsSize; @@ -818,14 +823,14 @@ comments: true void extendCapacity() { // 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组 int newCapacity = capacity() * extendRatio; - int* extend = new int[newCapacity]; + int* tmp = nums; + nums = new int[newCapacity]; // 将原数组中的所有元素复制到新数组 for (int i = 0; i < size(); i++) { - extend[i] = nums[i]; + nums[i] = tmp[i]; } - int* temp = nums; - nums = extend; - delete[] temp; + // 释放内存 + delete[] tmp; numsCapacity = newCapacity; } }; diff --git a/docs/chapter_computational_complexity/space_complexity.md b/docs/chapter_computational_complexity/space_complexity.md index e594bec8d..96873fc12 100644 --- a/docs/chapter_computational_complexity/space_complexity.md +++ b/docs/chapter_computational_complexity/space_complexity.md @@ -507,7 +507,7 @@ $$ const int a = 0; int b = 0; vector nums(10000); - ListNode* node = new ListNode(0); + ListNode node(0); // 循环中的变量占用 O(1) 空间 for (int i = 0; i < n; i++) { int c = 0; @@ -654,9 +654,9 @@ $$ // 长度为 n 的数组占用 O(n) 空间 vector nums(n); // 长度为 n 的列表占用 O(n) 空间 - vector nodes; + vector nodes; for (int i = 0; i < n; i++) { - nodes.push_back(new ListNode(i)); + nodes.push_back(ListNode(i)); } // 长度为 n 的哈希表占用 O(n) 空间 unordered_map map; diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index d70b3e528..51165331a 100644 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -330,6 +330,10 @@ comments: true rear = nullptr; queSize = 0; } + ~LinkedListQueue() { + delete front; + delete rear; + } /* 获取队列的长度 */ int size() { return queSize; @@ -784,6 +788,9 @@ comments: true cap = capacity; nums = new int[capacity]; } + ~ArrayQueue() { + delete[] nums; + } /* 获取队列的容量 */ int capacity() { return cap; diff --git a/docs/chapter_stack_and_queue/stack.md b/docs/chapter_stack_and_queue/stack.md index c47f7cc82..66b461875 100644 --- a/docs/chapter_stack_and_queue/stack.md +++ b/docs/chapter_stack_and_queue/stack.md @@ -324,6 +324,9 @@ comments: true stackTop = nullptr; stkSize = 0; } + ~LinkedListStack() { + freeMemoryLinkedList(stackTop); + } /* 获取栈的长度 */ int size() { return stkSize; diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index a0322154e..ca8a92021 100644 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -22,19 +22,15 @@ comments: true - 若 `cur.val = num` ,说明找到目标结点,跳出循环并返回该结点即可; === "Step 1" - ![bst_search_1](binary_search_tree.assets/bst_search_1.png) === "Step 2" - ![bst_search_2](binary_search_tree.assets/bst_search_2.png) === "Step 3" - ![bst_search_3](binary_search_tree.assets/bst_search_3.png) === "Step 4" - ![bst_search_4](binary_search_tree.assets/bst_search_4.png) 二叉搜索树的查找操作和二分查找算法如出一辙,也是在每轮排除一半情况。循环次数最多为二叉树的高度,当二叉树平衡时,使用 $O(\log n)$ 时间。