From 731e98fc252a513e3882fd23db33143ff1b2b4c4 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Sun, 27 Nov 2022 19:07:35 +0800 Subject: [PATCH] Add C++ codes for the chapter array and linked list. --- README.md | 2 +- .../chapter_array_and_linkedlist/array.cpp | 103 +++++++++++ .../linked_list.cpp | 77 ++++++++ .../cpp/chapter_array_and_linkedlist/list.cpp | 66 +++++++ .../chapter_array_and_linkedlist/my_list.cpp | 153 ++++++++++++++++ codes/cpp/include/PrintUtil.hpp | 16 ++ .../chapter_array_and_linkedlist/my_list.java | 20 +- .../chapter_array_and_linkedlist/my_list.py | 12 +- docs/chapter_array_and_linkedlist/array.md | 61 ++++++- .../linked_list.md | 67 ++++++- docs/chapter_array_and_linkedlist/list.md | 172 ++++++++++++++++-- 11 files changed, 705 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 98ce4ca91..560d6022c 100644 --- a/README.md +++ b/README.md @@ -54,4 +54,4 @@ ## License -The **texts, codes, images, photos, and videos** present on this work is licensed under [CC BY-NC-SA-4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). +The **texts, codes, images, photos, and videos** in this repository is licensed under [CC BY-NC-SA-4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/). diff --git a/codes/cpp/chapter_array_and_linkedlist/array.cpp b/codes/cpp/chapter_array_and_linkedlist/array.cpp index 422bcc428..fb620dbbd 100644 --- a/codes/cpp/chapter_array_and_linkedlist/array.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/array.cpp @@ -6,3 +6,106 @@ #include "../include/include.hpp" +/* 随机返回一个数组元素 */ +int randomAccess(int* nums, int size) { + // 在区间 [0, size) 中随机抽取一个数字 + int randomIndex = rand() % size; + // 获取并返回随机元素 + int randomNum = nums[randomIndex]; + return randomNum; +} + +/* 扩展数组长度 */ +int* extend(int* nums, int size, int enlarge) { + // 初始化一个扩展长度后的数组 + int* res = new int[size + enlarge]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < size; i++) { + res[i] = nums[i]; + } + // 返回扩展后的新数组 + return res; +} + +/* 在数组的索引 index 处插入元素 num */ +void insert(int* nums, int size, int num, int index) { + // 把索引 index 以及之后的所有元素向后移动一位 + for (int i = size - 1; i >= index; i--) { + nums[i] = nums[i - 1]; + } + // 将 num 赋给 index 处元素 + nums[index] = num; +} + +/* 删除索引 index 处元素 */ +void remove(int* nums, int size, int index) { + // 把索引 index 之后的所有元素向前移动一位 + for (int i = index; i < size - 1; i++) { + nums[i] = nums[i + 1]; + } +} + +/* 遍历数组 */ +void traverse(int* nums, int size) { + int count = 0; + // 通过索引遍历数组 + for (int i = 0; i < size; i++) { + count++; + } +} + +/* 在数组中查找指定元素 */ +int find(int* nums, int size, int target) { + for (int i = 0; i < size; i++) { + if (nums[i] == target) + return i; + } + return -1; +} + + +/* Driver Code */ +int main() { + /* 初始化数组 */ + int size = 5; + int* arr = new int[size]; + cout << "数组 arr = "; + PrintUtil::printArray(arr, size); + + int* nums = new int[size] { 1, 3, 2, 5, 4 }; + cout << "数组 nums = "; + PrintUtil::printArray(nums, size); + + /* 随机访问 */ + int randomNum = randomAccess(nums, size); + cout << "在 nums 中获取随机元素 " << randomNum << endl; + + /* 长度扩展 */ + int enlarge = 3; + int* res = extend(nums, size, enlarge); + int* temp = nums; + nums = res; + delete[] temp; + size += enlarge; + cout << "将数组长度扩展至 8 ,得到 nums = "; + PrintUtil::printArray(nums, size); + + /* 插入元素 */ + insert(nums, size, 6, 3); + cout << "在索引 3 处插入数字 6 ,得到 nums = "; + PrintUtil::printArray(nums, size); + + /* 删除元素 */ + remove(nums, size, 2); + cout << "删除索引 2 处的元素,得到 nums = "; + PrintUtil::printArray(nums, size); + + /* 遍历数组 */ + traverse(nums, size); + + /* 查找元素 */ + int index = find(nums, size, 3); + cout << "在 nums 中查找元素 3 ,得到索引 = " << index << endl; + + 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 092045b20..46116d291 100644 --- a/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/linked_list.cpp @@ -6,3 +6,80 @@ #include "../include/include.hpp" +/* 在链表的结点 n0 之后插入结点 P */ +void insert(ListNode* n0, ListNode* P) { + ListNode* n1 = n0->next; + n0->next = P; + P->next = n1; +} + +/* 删除链表的结点 n0 之后的首个结点 */ +void remove(ListNode* n0) { + if (n0->next == nullptr) + return; + // n0 -> P -> n1 + ListNode* P = n0->next; + ListNode* n1 = P->next; + n0->next = n1; +} + +/* 访问链表中索引为 index 的结点 */ +ListNode* access(ListNode* head, int index) { + for (int i = 0; i < index; i++) { + head = head->next; + if (head == nullptr) + return nullptr; + } + return head; +} + +/* 在链表中查找值为 target 的首个结点 */ +int find(ListNode* head, int target) { + int index = 0; + while (head != nullptr) { + if (head->val == target) + return index; + head = head->next; + index++; + } + return -1; +} + + +/* Driver Code */ +int main() { + /* 初始化链表 */ + // 初始化各个结点 + ListNode* n0 = new ListNode(1); + ListNode* n1 = new ListNode(3); + ListNode* n2 = new ListNode(2); + ListNode* n3 = new ListNode(5); + ListNode* n4 = new ListNode(4); + // 构建引用指向 + n0->next = n1; + n1->next = n2; + n2->next = n3; + n3->next = n4; + cout << "初始化的链表为" << endl; + PrintUtil::printLinkedList(n0); + + /* 插入结点 */ + insert(n0, new ListNode(0)); + cout << "插入结点后的链表为" << endl; + PrintUtil::printLinkedList(n0); + + /* 删除结点 */ + remove(n0); + cout << "删除结点后的链表为" << endl; + PrintUtil::printLinkedList(n0); + + /* 访问结点 */ + ListNode* node = access(n0, 3); + cout << "链表中索引 3 处的结点的值 = " << node->val << endl; + + /* 查找结点 */ + int index = find(n0, 2); + cout << "链表中值为 2 的结点的索引 = " << index << endl; + + return 0; +} diff --git a/codes/cpp/chapter_array_and_linkedlist/list.cpp b/codes/cpp/chapter_array_and_linkedlist/list.cpp index 06e28189b..287cae1bb 100644 --- a/codes/cpp/chapter_array_and_linkedlist/list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/list.cpp @@ -6,3 +6,69 @@ #include "../include/include.hpp" + +/* Driver Code */ +int main() { + /* 初始化列表 */ + vector list = { 1, 3, 2, 5, 4 }; + cout << "列表 list = "; + PrintUtil::printVector(list); + + /* 访问元素 */ + int num = list[1]; + cout << "访问索引 1 处的元素,得到 num = " << num << endl; + + /* 更新元素 */ + list[1] = 0; + cout << "将索引 1 处的元素更新为 0 ,得到 list = "; + PrintUtil::printVector(list); + + /* 清空列表 */ + list.clear(); + cout << "清空列表后 list = "; + PrintUtil::printVector(list); + + /* 尾部添加元素 */ + list.push_back(1); + list.push_back(3); + list.push_back(2); + list.push_back(5); + list.push_back(4); + cout << "添加元素后 list = "; + PrintUtil::printVector(list); + + /* 中间插入元素 */ + list.insert(list.begin() + 3, 6); + cout << "在索引 3 处插入数字 6 ,得到 list = "; + PrintUtil::printVector(list); + + /* 删除元素 */ + list.erase(list.begin() + 3); + cout << "删除索引 3 处的元素,得到 list = "; + PrintUtil::printVector(list); + + /* 通过索引遍历列表 */ + int count = 0; + for (int i = 0; i < list.size(); i++) { + count++; + } + + /* 直接遍历列表元素 */ + count = 0; + for (int n : list) { + count++; + } + + /* 拼接两个列表 */ + vector list1 = { 6, 8, 7, 10, 9 }; + list.insert(list.end(), list1.begin(), list1.end()); + cout << "将列表 list1 拼接到 list 之后,得到 list = "; + PrintUtil::printVector(list); + + /* 排序列表 */ + sort(list.begin(), list.end()); + cout << "排序列表后 list = "; + PrintUtil::printVector(list); + + 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 6b24eed53..5c530ddef 100644 --- a/codes/cpp/chapter_array_and_linkedlist/my_list.cpp +++ b/codes/cpp/chapter_array_and_linkedlist/my_list.cpp @@ -6,3 +6,156 @@ #include "../include/include.hpp" +/* 列表类简易实现 */ +class MyList { +private: + int* nums; // 数组(存储列表元素) + int numsCapacity = 10; // 列表容量 + int numsSize = 0; // 列表长度(即当前元素数量) + int extendRatio = 2; // 每次列表扩容的倍数 + +public: + /* 构造函数 */ + MyList() { + nums = new int[numsCapacity]; + } + + /* 获取列表长度(即当前元素数量)*/ + int size() { + return numsSize; + } + + /* 获取列表容量 */ + int capacity() { + return numsCapacity; + } + + /* 访问元素 */ + int get(int index) { + // 索引如果越界则抛出异常,下同 + if (index >= size()) + throw std::out_of_range ("索引越界"); + return nums[index]; + } + + /* 更新元素 */ + void set(int index, int num) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + nums[index] = num; + } + + /* 尾部添加元素 */ + void add(int num) { + // 元素数量超出容量时,触发扩容机制 + if (size() == capacity()) + extendCapacity(); + nums[size()] = num; + // 更新元素数量 + numsSize++; + } + + /* 中间插入元素 */ + void insert(int index, int num) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + // 元素数量超出容量时,触发扩容机制 + if (size() == capacity()) + extendCapacity(); + // 索引 i 以及之后的元素都向后移动一位 + for (int j = size() - 1; j >= index; j--) { + nums[j + 1] = nums[j]; + } + nums[index] = num; + // 更新元素数量 + numsSize++; + } + + /* 删除元素 */ + void remove(int index) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + // 索引 i 之后的元素都向前移动一位 + for (int j = index; j < size() - 1; j++) { + nums[j] = nums[j + 1]; + } + // 更新元素数量 + numsSize--; + } + + /* 列表扩容 */ + void extendCapacity() { + // 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组 + int newCapacity = capacity() * extendRatio; + int* extend = new int[newCapacity]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < size(); i++) { + extend[i] = nums[i]; + } + int* temp = nums; + nums = extend; + delete[] temp; + numsCapacity = newCapacity; + } + + /* 将列表转换为 Vector 用于打印 */ + vector toVector() { + // 仅转换有效长度范围内的列表元素 + vector vec(size()); + for (int i = 0; i < size(); i++) { + vec[i] = nums[i]; + } + return vec; + } +}; + + +/* Driver Code */ +int main() { + /* 初始化列表 */ + MyList *list = new MyList(); + /* 尾部添加元素 */ + list->add(1); + list->add(3); + list->add(2); + list->add(5); + list->add(4); + cout << "列表 list = "; + vector vec = list->toVector(); + PrintUtil::printVector(vec); + cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl; + + /* 中间插入元素 */ + list->insert(3, 6); + cout << "在索引 3 处插入数字 6 ,得到 list = "; + vec = list->toVector(); + PrintUtil::printVector(vec); + + /* 删除元素 */ + list->remove(3); + cout << "删除索引 3 处的元素,得到 list = "; + vec = list->toVector(); + PrintUtil::printVector(vec); + + /* 访问元素 */ + int num = list->get(1); + cout << "访问索引 1 处的元素,得到 num = " << num << endl; + + /* 更新元素 */ + list->set(1, 0); + cout << "将索引 1 处的元素更新为 0 ,得到 list = "; + vec = list->toVector(); + PrintUtil::printVector(vec); + + /* 测试扩容机制 */ + for (int i = 0; i < 10; i++) { + // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 + list->add(i); + } + cout << "扩容后的列表 list = "; + vec = list->toVector(); + PrintUtil::printVector(vec); + cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl; + + return 0; +} diff --git a/codes/cpp/include/PrintUtil.hpp b/codes/cpp/include/PrintUtil.hpp index 34e8b8687..b85da88ef 100644 --- a/codes/cpp/include/PrintUtil.hpp +++ b/codes/cpp/include/PrintUtil.hpp @@ -67,6 +67,22 @@ class PrintUtil { return os.str(); } + /** + * @brief Print an Array + * + * @tparam T + * @tparam n + */ + template + static void printArray(T* arr, int n) + { + cout << "["; + for (size_t i = 0; i < n - 1; i++) { + cout << arr[i] << ", "; + } + cout << arr[n - 1] << "]" << '\n'; + } + /** * @brief Get the Vector String object * diff --git a/codes/java/chapter_array_and_linkedlist/my_list.java b/codes/java/chapter_array_and_linkedlist/my_list.java index d4db0a2c3..74153b021 100644 --- a/codes/java/chapter_array_and_linkedlist/my_list.java +++ b/codes/java/chapter_array_and_linkedlist/my_list.java @@ -10,14 +10,14 @@ import java.util.*; /* 列表类简易实现 */ class MyList { - int[] nums; // 数组(存储列表元素) - int initialCapacity = 10; // 列表初始容量 - int size = 0; // 列表长度(即当前元素数量) - int extendRatio = 2; // 每次列表扩容的倍数 + private int[] nums; // 数组(存储列表元素) + private int capacity = 10; // 列表容量 + private int size = 0; // 列表长度(即当前元素数量) + private int extendRatio = 2; // 每次列表扩容的倍数 /* 构造函数 */ public MyList() { - nums = new int[initialCapacity]; + nums = new int[capacity]; } /* 获取列表长度(即当前元素数量)*/ @@ -27,7 +27,7 @@ class MyList { /* 获取列表容量 */ public int capacity() { - return nums.length; + return capacity; } /* 访问元素 */ @@ -48,7 +48,7 @@ class MyList { /* 尾部添加元素 */ public void add(int num) { // 元素数量超出容量时,触发扩容机制 - if (size == nums.length) + if (size == capacity()) extendCapacity(); nums[size] = num; // 更新元素数量 @@ -60,7 +60,7 @@ class MyList { if (index >= size) throw new IndexOutOfBoundsException("索引越界"); // 元素数量超出容量时,触发扩容机制 - if (size == nums.length) + if (size == capacity()) extendCapacity(); // 索引 i 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { @@ -86,7 +86,9 @@ class MyList { /* 列表扩容 */ public void extendCapacity() { // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 - nums = Arrays.copyOf(nums, nums.length * extendRatio); + nums = Arrays.copyOf(nums, capacity() * extendRatio); + // 更新列表容量 + capacity = nums.length; } /* 将列表转换为数组 */ diff --git a/codes/python/chapter_array_and_linkedlist/my_list.py b/codes/python/chapter_array_and_linkedlist/my_list.py index 54a75b338..1c178fc09 100644 --- a/codes/python/chapter_array_and_linkedlist/my_list.py +++ b/codes/python/chapter_array_and_linkedlist/my_list.py @@ -12,10 +12,10 @@ from include import * class MyList: """ 构造函数 """ def __init__(self): - self._initial_capacity = 10 # 列表初始容量 - self._nums = [0] * self._initial_capacity # 数组(存储列表元素) - self._size = 0 # 列表长度(即当前元素数量) - self._extend_ratio = 2 # 每次列表扩容的倍数 + self._capacity = 10 # 列表容量 + self._nums = [0] * self._capacity # 数组(存储列表元素) + self._size = 0 # 列表长度(即当前元素数量) + self._extend_ratio = 2 # 每次列表扩容的倍数 """ 获取列表长度(即当前元素数量) """ def size(self): @@ -23,7 +23,7 @@ class MyList: """ 获取列表容量 """ def capacity(self): - return len(self._nums) + return self._capacity """ 访问元素 """ def get(self, index): @@ -64,6 +64,8 @@ class MyList: def extend_capacity(self): # 新建一个长度为 self._size 的数组,并将原数组拷贝到新数组 self._nums = self._nums + [0] * self.capacity() * (self._extend_ratio - 1) + # 更新列表容量 + self._capacity = len(self._nums) """ 返回有效长度的列表 """ def to_array(self): diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index 14a24ab0e..df8bc3535 100644 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -27,7 +27,9 @@ comments: true === "C++" ```cpp title="array.cpp" - + /* 初始化数组 */ + int* arr = new int[5]; + int* nums = new int[5] { 1, 3, 2, 5, 4 }; ``` === "Python" @@ -70,7 +72,14 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C++" ```cpp title="array.cpp" - + /* 随机返回一个数组元素 */ + int randomAccess(int* nums, int size) { + // 在区间 [0, size) 中随机抽取一个数字 + int randomIndex = rand() % size; + // 获取并返回随机元素 + int randomNum = nums[randomIndex]; + return randomNum; + } ``` === "Python" @@ -108,7 +117,17 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C++" ```cpp title="array.cpp" - + /* 扩展数组长度 */ + int* extend(int* nums, int size, int enlarge) { + // 初始化一个扩展长度后的数组 + int* res = new int[size + enlarge]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < size; i++) { + res[i] = nums[i]; + } + // 返回扩展后的新数组 + return res; + } ``` === "Python" @@ -160,7 +179,23 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C++" ```cpp title="array.cpp" - + /* 在数组的索引 index 处插入元素 num */ + void insert(int* nums, int size, int num, int index) { + // 把索引 index 以及之后的所有元素向后移动一位 + for (int i = size - 1; i >= index; i--) { + nums[i] = nums[i - 1]; + } + // 将 num 赋给 index 处元素 + nums[index] = num; + } + + /* 删除索引 index 处元素 */ + void remove(int* nums, int size, int index) { + // 把索引 index 之后的所有元素向前移动一位 + for (int i = index; i < size - 1; i++) { + nums[i] = nums[i + 1]; + } + } ``` === "Python" @@ -205,7 +240,14 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C++" ```cpp title="array.cpp" - + /* 遍历数组 */ + void traverse(int* nums, int size) { + int count = 0; + // 通过索引遍历数组 + for (int i = 0; i < size; i++) { + count++; + } + } ``` === "Python" @@ -240,7 +282,14 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "C++" ```cpp title="array.cpp" - + /* 在数组中查找指定元素 */ + int find(int* nums, int size, int target) { + for (int i = 0; i < size; i++) { + if (nums[i] == target) + return i; + } + return -1; + } ``` === "Python" diff --git a/docs/chapter_array_and_linkedlist/linked_list.md b/docs/chapter_array_and_linkedlist/linked_list.md index 51da06134..79dee24ac 100644 --- a/docs/chapter_array_and_linkedlist/linked_list.md +++ b/docs/chapter_array_and_linkedlist/linked_list.md @@ -30,7 +30,12 @@ comments: true === "C++" ```cpp title="" - + /* 链表结点结构体 */ + struct ListNode { + int val; // 结点值 + ListNode *next; // 指向下一结点的指针(引用) + ListNode(int x) : val(x), next(nullptr) {} // 构造函数 + }; ``` === "Python" @@ -71,7 +76,18 @@ comments: true === "C++" ```cpp title="" - + /* 初始化链表 1 -> 3 -> 2 -> 5 -> 4 */ + // 初始化各个结点 + ListNode* n0 = new ListNode(1); + ListNode* n1 = new ListNode(3); + ListNode* n2 = new ListNode(2); + ListNode* n3 = new ListNode(5); + ListNode* n4 = new ListNode(4); + // 构建引用指向 + n0->next = n1; + n1->next = n2; + n2->next = n3; + n3->next = n4; ``` === "Python" @@ -123,7 +139,22 @@ comments: true === "C++" ```cpp title="" - + /* 在链表的结点 n0 之后插入结点 P */ + void insert(ListNode* n0, ListNode* P) { + ListNode* n1 = n0->next; + n0->next = P; + P->next = n1; + } + + /* 删除链表的结点 n0 之后的首个结点 */ + void remove(ListNode* n0) { + if (n0->next == nullptr) + return; + // n0 -> P -> n1 + ListNode* P = n0->next; + ListNode* n1 = P->next; + n0->next = n1; + } ``` === "Python" @@ -166,7 +197,15 @@ comments: true === "C++" ```cpp title="" - + /* 访问链表中索引为 index 的结点 */ + ListNode* access(ListNode* head, int index) { + for (int i = 0; i < index; i++) { + head = head->next; + if (head == nullptr) + return nullptr; + } + return head; + } ``` === "Python" @@ -206,7 +245,17 @@ comments: true === "C++" ```cpp title="" - + /* 在链表中查找值为 target 的首个结点 */ + int find(ListNode* head, int target) { + int index = 0; + while (head != nullptr) { + if (head->val == target) + return index; + head = head->next; + index++; + } + return -1; + } ``` === "Python" @@ -246,7 +295,13 @@ comments: true === "C++" ```cpp title="" - + /* 链表结点结构体 */ + struct ListNode { + int val; // 结点值 + ListNode *next; // 指向后继结点的指针(引用) + ListNode *prev; // 指向前驱结点的指针(引用) + ListNode(int x) : val(x), next(nullptr) {} // 构造函数 + }; ``` === "Python" diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index e6308605d..a8310ec68 100644 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -24,7 +24,8 @@ comments: true === "C++" ```cpp title="list.cpp" - + /* 初始化列表 */ + vector list = { 1, 3, 2, 5, 4 }; ``` === "Python" @@ -49,7 +50,11 @@ comments: true === "C++" ```cpp title="list.cpp" + /* 访问元素 */ + int num = list[1]; // 访问索引 1 处的元素 + /* 更新元素 */ + list[1] = 0; // 将索引 1 处的元素更新为 0 ``` === "Python" @@ -87,7 +92,21 @@ comments: true === "C++" ```cpp title="list.cpp" + /* 清空列表 */ + list.clear(); + /* 尾部添加元素 */ + list.push_back(1); + list.push_back(3); + list.push_back(2); + list.push_back(5); + list.push_back(4); + + /* 中间插入元素 */ + list.insert(list.begin() + 3, 6); // 在索引 3 处插入数字 6 + + /* 删除元素 */ + list.erase(list.begin() + 3); // 删除索引 3 处的元素 ``` === "Python" @@ -131,7 +150,17 @@ comments: true === "C++" ```cpp title="list.cpp" + /* 通过索引遍历列表 */ + int count = 0; + for (int i = 0; i < list.size(); i++) { + count++; + } + /* 直接遍历列表元素 */ + count = 0; + for (int n : list) { + count++; + } ``` === "Python" @@ -161,7 +190,10 @@ comments: true === "C++" ```cpp title="list.cpp" - + /* 拼接两个列表 */ + vector list1 = { 6, 8, 7, 10, 9 }; + // 将列表 list1 拼接到 list 之后 + list.insert(list.end(), list1.begin(), list1.end()); ``` === "Python" @@ -184,7 +216,8 @@ comments: true === "C++" ```cpp title="list.cpp" - + /* 排序列表 */ + sort(list.begin(), list.end()); // 排序后,列表元素从小到大排列 ``` === "Python" @@ -209,14 +242,14 @@ comments: true ```java title="my_list.java" /* 列表类简易实现 */ class MyList { - int[] nums; // 数组(存储列表元素) - int initialCapacity = 10; // 列表初始容量 - int size = 0; // 列表长度(即当前元素数量) - int extendRatio = 2; // 每次列表扩容的倍数 + private int[] nums; // 数组(存储列表元素) + private int capacity = 10; // 列表容量 + private int size = 0; // 列表长度(即当前元素数量) + private int extendRatio = 2; // 每次列表扩容的倍数 /* 构造函数 */ public MyList() { - nums = new int[initialCapacity]; + nums = new int[capacity]; } /* 获取列表长度(即当前元素数量)*/ @@ -226,7 +259,7 @@ comments: true /* 获取列表容量 */ public int capacity() { - return nums.length; + return capacity; } /* 访问元素 */ @@ -247,7 +280,7 @@ comments: true /* 尾部添加元素 */ public void add(int num) { // 元素数量超出容量时,触发扩容机制 - if (size == nums.length) + if (size == capacity()) extendCapacity(); nums[size] = num; // 更新元素数量 @@ -259,7 +292,7 @@ comments: true if (index >= size) throw new IndexOutOfBoundsException("索引越界"); // 元素数量超出容量时,触发扩容机制 - if (size == nums.length) + if (size == capacity()) extendCapacity(); // 索引 i 以及之后的元素都向后移动一位 for (int j = size - 1; j >= index; j--) { @@ -285,7 +318,9 @@ comments: true /* 列表扩容 */ public void extendCapacity() { // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 - nums = Arrays.copyOf(nums, nums.length * extendRatio); + nums = Arrays.copyOf(nums, capacity() * extendRatio); + // 更新列表容量 + capacity = nums.length; } } ``` @@ -293,7 +328,108 @@ comments: true === "C++" ```cpp title="my_list.cpp" + /* 列表类简易实现 */ + class MyList { + private: + int* nums; // 数组(存储列表元素) + int numsCapacity = 10; // 列表容量 + int numsSize = 0; // 列表长度(即当前元素数量) + int extendRatio = 2; // 每次列表扩容的倍数 + public: + /* 构造函数 */ + MyList() { + nums = new int[numsCapacity]; + } + + /* 获取列表长度(即当前元素数量)*/ + int size() { + return numsSize; + } + + /* 获取列表容量 */ + int capacity() { + return numsCapacity; + } + + /* 访问元素 */ + int get(int index) { + // 索引如果越界则抛出异常,下同 + if (index >= size()) + throw std::out_of_range ("索引越界"); + return nums[index]; + } + + /* 更新元素 */ + void set(int index, int num) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + nums[index] = num; + } + + /* 尾部添加元素 */ + void add(int num) { + // 元素数量超出容量时,触发扩容机制 + if (size() == capacity()) + extendCapacity(); + nums[size()] = num; + // 更新元素数量 + numsSize++; + } + + /* 中间插入元素 */ + void insert(int index, int num) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + // 元素数量超出容量时,触发扩容机制 + if (size() == capacity()) + extendCapacity(); + // 索引 i 以及之后的元素都向后移动一位 + for (int j = size() - 1; j >= index; j--) { + nums[j + 1] = nums[j]; + } + nums[index] = num; + // 更新元素数量 + numsSize++; + } + + /* 删除元素 */ + void remove(int index) { + if (index >= size()) + throw std::out_of_range ("索引越界"); + // 索引 i 之后的元素都向前移动一位 + for (int j = index; j < size() - 1; j++) { + nums[j] = nums[j + 1]; + } + // 更新元素数量 + numsSize--; + } + + /* 列表扩容 */ + void extendCapacity() { + // 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组 + int newCapacity = capacity() * extendRatio; + int* extend = new int[newCapacity]; + // 将原数组中的所有元素复制到新数组 + for (int i = 0; i < size(); i++) { + extend[i] = nums[i]; + } + int* temp = nums; + nums = extend; + delete[] temp; + numsCapacity = newCapacity; + } + + /* 将列表转换为 Vector 用于打印 */ + vector toVector() { + // 仅转换有效长度范围内的列表元素 + vector vec(size()); + for (int i = 0; i < size(); i++) { + vec[i] = nums[i]; + } + return vec; + } + }; ``` === "Python" @@ -303,10 +439,10 @@ comments: true class MyList: """ 构造函数 """ def __init__(self): - self._initial_capacity = 10 # 列表初始容量 - self._nums = [0] * self._initial_capacity # 数组(存储列表元素) - self._size = 0 # 列表长度(即当前元素数量) - self._extend_ratio = 2 # 每次列表扩容的倍数 + self._capacity = 10 # 列表容量 + self._nums = [0] * self._capacity # 数组(存储列表元素) + self._size = 0 # 列表长度(即当前元素数量) + self._extend_ratio = 2 # 每次列表扩容的倍数 """ 获取列表长度(即当前元素数量) """ def size(self): @@ -314,7 +450,7 @@ comments: true """ 获取列表容量 """ def capacity(self): - return len(self._nums) + return self._capacity """ 访问元素 """ def get(self, index): @@ -355,4 +491,6 @@ comments: true def extend_capacity(self): # 新建一个长度为 self._size 的数组,并将原数组拷贝到新数组 self._nums = self._nums + [0] * self.capacity() * (self._extend_ratio - 1) + # 更新列表容量 + self._capacity = len(self._nums) ```