Format C++ codes in Clang-Format Style: Microsoft

This commit is contained in:
krahets 2023-04-14 03:44:02 +08:00
parent f8513455b5
commit 9c9c8b7574
46 changed files with 732 additions and 888 deletions

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 随机返回一个数组元素 */ /* 随机返回一个数组元素 */
int randomAccess(int* nums, int size) { int randomAccess(int *nums, int size) {
// 在区间 [0, size) 中随机抽取一个数字 // 在区间 [0, size) 中随机抽取一个数字
int randomIndex = rand() % size; int randomIndex = rand() % size;
// 获取并返回随机元素 // 获取并返回随机元素
@ -16,9 +16,9 @@ int randomAccess(int* nums, int size) {
} }
/* 扩展数组长度 */ /* 扩展数组长度 */
int* extend(int* nums, int size, int enlarge) { int *extend(int *nums, int size, int enlarge) {
// 初始化一个扩展长度后的数组 // 初始化一个扩展长度后的数组
int* res = new int[size + enlarge]; int *res = new int[size + enlarge];
// 将原数组中的所有元素复制到新数组 // 将原数组中的所有元素复制到新数组
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
res[i] = nums[i]; res[i] = nums[i];
@ -30,7 +30,7 @@ int* extend(int* nums, int size, int enlarge) {
} }
/* 在数组的索引 index 处插入元素 num */ /* 在数组的索引 index 处插入元素 num */
void insert(int* nums, int size, int num, int index) { void insert(int *nums, int size, int num, int index) {
// 把索引 index 以及之后的所有元素向后移动一位 // 把索引 index 以及之后的所有元素向后移动一位
for (int i = size - 1; i > index; i--) { for (int i = size - 1; i > index; i--) {
nums[i] = nums[i - 1]; nums[i] = nums[i - 1];
@ -40,7 +40,7 @@ void insert(int* nums, int size, int num, int index) {
} }
/* 删除索引 index 处元素 */ /* 删除索引 index 处元素 */
void remove(int* nums, int size, int index) { void remove(int *nums, int size, int index) {
// 把索引 index 之后的所有元素向前移动一位 // 把索引 index 之后的所有元素向前移动一位
for (int i = index; i < size - 1; i++) { for (int i = index; i < size - 1; i++) {
nums[i] = nums[i + 1]; nums[i] = nums[i + 1];
@ -48,7 +48,7 @@ void remove(int* nums, int size, int index) {
} }
/* 遍历数组 */ /* 遍历数组 */
void traverse(int* nums, int size) { void traverse(int *nums, int size) {
int count = 0; int count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -57,7 +57,7 @@ void traverse(int* nums, int size) {
} }
/* 在数组中查找指定元素 */ /* 在数组中查找指定元素 */
int find(int* nums, int size, int target) { int find(int *nums, int size, int target) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (nums[i] == target) if (nums[i] == target)
return i; return i;
@ -65,43 +65,42 @@ int find(int* nums, int size, int target) {
return -1; return -1;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化数组 */ /* 初始化数组 */
int size = 5; int size = 5;
int* arr = new int[size]; int *arr = new int[size];
cout << "数组 arr = "; cout << "数组 arr = ";
PrintUtil::printArray(arr, size); printArray(arr, size);
int* nums = new int[size] { 1, 3, 2, 5, 4 }; int *nums = new int[size]{1, 3, 2, 5, 4};
cout << "数组 nums = "; cout << "数组 nums = ";
PrintUtil::printArray(nums, size); printArray(nums, size);
/* 随机访问 */ /* 随机访问 */
int randomNum = randomAccess(nums, size); int randomNum = randomAccess(nums, size);
cout << "在 nums 中获取随机元素 " << randomNum << endl; cout << "在 nums 中获取随机元素 " << randomNum << endl;
/* 长度扩展 */ /* 长度扩展 */
int enlarge = 3; int enlarge = 3;
nums = extend(nums, size, enlarge); nums = extend(nums, size, enlarge);
size += enlarge; size += enlarge;
cout << "将数组长度扩展至 8 ,得到 nums = "; cout << "将数组长度扩展至 8 ,得到 nums = ";
PrintUtil::printArray(nums, size); printArray(nums, size);
/* 插入元素 */ /* 插入元素 */
insert(nums, size, 6, 3); insert(nums, size, 6, 3);
cout << "在索引 3 处插入数字 6 ,得到 nums = "; cout << "在索引 3 处插入数字 6 ,得到 nums = ";
PrintUtil::printArray(nums, size); printArray(nums, size);
/* 删除元素 */ /* 删除元素 */
remove(nums, size, 2); remove(nums, size, 2);
cout << "删除索引 2 处的元素,得到 nums = "; cout << "删除索引 2 处的元素,得到 nums = ";
PrintUtil::printArray(nums, size); printArray(nums, size);
/* 遍历数组 */ /* 遍历数组 */
traverse(nums, size); traverse(nums, size);
/* 查找元素 */ /* 查找元素 */
int index = find(nums, size, 3); int index = find(nums, size, 3);
cout << "在 nums 中查找元素 3 ,得到索引 = " << index << endl; cout << "在 nums 中查找元素 3 ,得到索引 = " << index << endl;

View File

@ -7,26 +7,26 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 在链表的节点 n0 之后插入节点 P */ /* 在链表的节点 n0 之后插入节点 P */
void insert(ListNode* n0, ListNode* P) { void insert(ListNode *n0, ListNode *P) {
ListNode* n1 = n0->next; ListNode *n1 = n0->next;
P->next = n1; P->next = n1;
n0->next = P; n0->next = P;
} }
/* 删除链表的节点 n0 之后的首个节点 */ /* 删除链表的节点 n0 之后的首个节点 */
void remove(ListNode* n0) { void remove(ListNode *n0) {
if (n0->next == nullptr) if (n0->next == nullptr)
return; return;
// n0 -> P -> n1 // n0 -> P -> n1
ListNode* P = n0->next; ListNode *P = n0->next;
ListNode* n1 = P->next; ListNode *n1 = P->next;
n0->next = n1; n0->next = n1;
// 释放内存 // 释放内存
delete P; delete P;
} }
/* 访问链表中索引为 index 的节点 */ /* 访问链表中索引为 index 的节点 */
ListNode* access(ListNode* head, int index) { ListNode *access(ListNode *head, int index) {
for (int i = 0; i < index; i++) { for (int i = 0; i < index; i++) {
if (head == nullptr) if (head == nullptr)
return nullptr; return nullptr;
@ -36,7 +36,7 @@ ListNode* access(ListNode* head, int index) {
} }
/* 在链表中查找值为 target 的首个节点 */ /* 在链表中查找值为 target 的首个节点 */
int find(ListNode* head, int target) { int find(ListNode *head, int target) {
int index = 0; int index = 0;
while (head != nullptr) { while (head != nullptr) {
if (head->val == target) if (head->val == target)
@ -47,36 +47,35 @@ int find(ListNode* head, int target) {
return -1; return -1;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化链表 */ /* 初始化链表 */
// 初始化各个节点 // 初始化各个节点
ListNode* n0 = new ListNode(1); ListNode *n0 = new ListNode(1);
ListNode* n1 = new ListNode(3); ListNode *n1 = new ListNode(3);
ListNode* n2 = new ListNode(2); ListNode *n2 = new ListNode(2);
ListNode* n3 = new ListNode(5); ListNode *n3 = new ListNode(5);
ListNode* n4 = new ListNode(4); ListNode *n4 = new ListNode(4);
// 构建引用指向 // 构建引用指向
n0->next = n1; n0->next = n1;
n1->next = n2; n1->next = n2;
n2->next = n3; n2->next = n3;
n3->next = n4; n3->next = n4;
cout << "初始化的链表为" << endl; cout << "初始化的链表为" << endl;
PrintUtil::printLinkedList(n0); printLinkedList(n0);
/* 插入节点 */ /* 插入节点 */
insert(n0, new ListNode(0)); insert(n0, new ListNode(0));
cout << "插入节点后的链表为" << endl; cout << "插入节点后的链表为" << endl;
PrintUtil::printLinkedList(n0); printLinkedList(n0);
/* 删除节点 */ /* 删除节点 */
remove(n0); remove(n0);
cout << "删除节点后的链表为" << endl; cout << "删除节点后的链表为" << endl;
PrintUtil::printLinkedList(n0); printLinkedList(n0);
/* 访问节点 */ /* 访问节点 */
ListNode* node = access(n0, 3); ListNode *node = access(n0, 3);
cout << "链表中索引 3 处的节点的值 = " << node->val << endl; cout << "链表中索引 3 处的节点的值 = " << node->val << endl;
/* 查找节点 */ /* 查找节点 */

View File

@ -6,13 +6,12 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化列表 */ /* 初始化列表 */
vector<int> list = { 1, 3, 2, 5, 4 }; vector<int> list = {1, 3, 2, 5, 4};
cout << "列表 list = "; cout << "列表 list = ";
PrintUtil::printVector(list); printVector(list);
/* 访问元素 */ /* 访问元素 */
int num = list[1]; int num = list[1];
@ -21,12 +20,12 @@ int main() {
/* 更新元素 */ /* 更新元素 */
list[1] = 0; list[1] = 0;
cout << "将索引 1 处的元素更新为 0 ,得到 list = "; cout << "将索引 1 处的元素更新为 0 ,得到 list = ";
PrintUtil::printVector(list); printVector(list);
/* 清空列表 */ /* 清空列表 */
list.clear(); list.clear();
cout << "清空列表后 list = "; cout << "清空列表后 list = ";
PrintUtil::printVector(list); printVector(list);
/* 尾部添加元素 */ /* 尾部添加元素 */
list.push_back(1); list.push_back(1);
@ -35,17 +34,17 @@ int main() {
list.push_back(5); list.push_back(5);
list.push_back(4); list.push_back(4);
cout << "添加元素后 list = "; cout << "添加元素后 list = ";
PrintUtil::printVector(list); printVector(list);
/* 中间插入元素 */ /* 中间插入元素 */
list.insert(list.begin() + 3, 6); list.insert(list.begin() + 3, 6);
cout << "在索引 3 处插入数字 6 ,得到 list = "; cout << "在索引 3 处插入数字 6 ,得到 list = ";
PrintUtil::printVector(list); printVector(list);
/* 删除元素 */ /* 删除元素 */
list.erase(list.begin() + 3); list.erase(list.begin() + 3);
cout << "删除索引 3 处的元素,得到 list = "; cout << "删除索引 3 处的元素,得到 list = ";
PrintUtil::printVector(list); printVector(list);
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
@ -60,15 +59,15 @@ int main() {
} }
/* 拼接两个列表 */ /* 拼接两个列表 */
vector<int> list1 = { 6, 8, 7, 10, 9 }; vector<int> list1 = {6, 8, 7, 10, 9};
list.insert(list.end(), list1.begin(), list1.end()); list.insert(list.end(), list1.begin(), list1.end());
cout << "将列表 list1 拼接到 list 之后,得到 list = "; cout << "将列表 list1 拼接到 list 之后,得到 list = ";
PrintUtil::printVector(list); printVector(list);
/* 排序列表 */ /* 排序列表 */
sort(list.begin(), list.end()); sort(list.begin(), list.end());
cout << "排序列表后 list = "; cout << "排序列表后 list = ";
PrintUtil::printVector(list); printVector(list);
return 0; return 0;
} }

View File

@ -8,13 +8,13 @@
/* 列表类简易实现 */ /* 列表类简易实现 */
class MyList { class MyList {
private: private:
int* nums; // 数组(存储列表元素) int *nums; // 数组(存储列表元素)
int numsCapacity = 10; // 列表容量 int numsCapacity = 10; // 列表容量
int numsSize = 0; // 列表长度(即当前元素数量) int numsSize = 0; // 列表长度(即当前元素数量)
int extendRatio = 2; // 每次列表扩容的倍数 int extendRatio = 2; // 每次列表扩容的倍数
public: public:
/* 构造方法 */ /* 构造方法 */
MyList() { MyList() {
nums = new int[numsCapacity]; nums = new int[numsCapacity];
@ -95,7 +95,7 @@ public:
void extendCapacity() { void extendCapacity() {
// 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组 // 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组
int newCapacity = capacity() * extendRatio; int newCapacity = capacity() * extendRatio;
int* tmp = nums; int *tmp = nums;
nums = new int[newCapacity]; nums = new int[newCapacity];
// 将原数组中的所有元素复制到新数组 // 将原数组中的所有元素复制到新数组
for (int i = 0; i < size(); i++) { for (int i = 0; i < size(); i++) {
@ -117,7 +117,6 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化列表 */ /* 初始化列表 */
@ -130,20 +129,20 @@ int main() {
list->add(4); list->add(4);
cout << "列表 list = "; cout << "列表 list = ";
vector<int> vec = list->toVector(); vector<int> vec = list->toVector();
PrintUtil::printVector(vec); printVector(vec);
cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl; cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl;
/* 中间插入元素 */ /* 中间插入元素 */
list->insert(3, 6); list->insert(3, 6);
cout << "在索引 3 处插入数字 6 ,得到 list = "; cout << "在索引 3 处插入数字 6 ,得到 list = ";
vec = list->toVector(); vec = list->toVector();
PrintUtil::printVector(vec); printVector(vec);
/* 删除元素 */ /* 删除元素 */
list->remove(3); list->remove(3);
cout << "删除索引 3 处的元素,得到 list = "; cout << "删除索引 3 处的元素,得到 list = ";
vec = list->toVector(); vec = list->toVector();
PrintUtil::printVector(vec); printVector(vec);
/* 访问元素 */ /* 访问元素 */
int num = list->get(1); int num = list->get(1);
@ -153,7 +152,7 @@ int main() {
list->set(1, 0); list->set(1, 0);
cout << "将索引 1 处的元素更新为 0 ,得到 list = "; cout << "将索引 1 处的元素更新为 0 ,得到 list = ";
vec = list->toVector(); vec = list->toVector();
PrintUtil::printVector(vec); printVector(vec);
/* 测试扩容机制 */ /* 测试扩容机制 */
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
@ -162,7 +161,7 @@ int main() {
} }
cout << "扩容后的列表 list = "; cout << "扩容后的列表 list = ";
vec = list->toVector(); vec = list->toVector();
PrintUtil::printVector(vec); printVector(vec);
cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl; cout << "容量 = " << list->capacity() << " ,长度 = " << list->size() << endl;
// 释放内存 // 释放内存

View File

@ -7,48 +7,47 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 方法一:暴力枚举 */ /* 方法一:暴力枚举 */
vector<int> twoSumBruteForce(vector<int>& nums, int target) { vector<int> twoSumBruteForce(vector<int> &nums, int target) {
int size = nums.size(); int size = nums.size();
// 两层循环,时间复杂度 O(n^2) // 两层循环,时间复杂度 O(n^2)
for (int i = 0; i < size - 1; i++) { for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) { for (int j = i + 1; j < size; j++) {
if (nums[i] + nums[j] == target) if (nums[i] + nums[j] == target)
return { i, j }; return {i, j};
} }
} }
return {}; return {};
} }
/* 方法二:辅助哈希表 */ /* 方法二:辅助哈希表 */
vector<int> twoSumHashTable(vector<int>& nums, int target) { vector<int> twoSumHashTable(vector<int> &nums, int target) {
int size = nums.size(); int size = nums.size();
// 辅助哈希表,空间复杂度 O(n) // 辅助哈希表,空间复杂度 O(n)
unordered_map<int, int> dic; unordered_map<int, int> dic;
// 单层循环,时间复杂度 O(n) // 单层循环,时间复杂度 O(n)
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (dic.find(target - nums[i]) != dic.end()) { if (dic.find(target - nums[i]) != dic.end()) {
return { dic[target - nums[i]], i }; return {dic[target - nums[i]], i};
} }
dic.emplace(nums[i], i); dic.emplace(nums[i], i);
} }
return {}; return {};
} }
int main() { int main() {
// ======= Test Case ======= // ======= Test Case =======
vector<int> nums = { 2,7,11,15 }; vector<int> nums = {2, 7, 11, 15};
int target = 9; int target = 9;
// ====== Driver Code ====== // ====== Driver Code ======
// 方法一 // 方法一
vector<int> res = twoSumBruteForce(nums, target); vector<int> res = twoSumBruteForce(nums, target);
cout << "方法一 res = "; cout << "方法一 res = ";
PrintUtil::printVector(res); printVector(res);
// 方法二 // 方法二
res = twoSumHashTable(nums, target); res = twoSumHashTable(nums, target);
cout << "方法二 res = "; cout << "方法二 res = ";
PrintUtil::printVector(res); printVector(res);
return 0; return 0;
} }

View File

@ -48,7 +48,8 @@ void linear(int n) {
/* 线性阶(递归实现) */ /* 线性阶(递归实现) */
void linearRecur(int n) { void linearRecur(int n) {
cout << "递归 n = " << n << endl; cout << "递归 n = " << n << endl;
if (n == 1) return; if (n == 1)
return;
linearRecur(n - 1); linearRecur(n - 1);
} }
@ -67,22 +68,23 @@ void quadratic(int n) {
/* 平方阶(递归实现) */ /* 平方阶(递归实现) */
int quadraticRecur(int n) { int quadraticRecur(int n) {
if (n <= 0) return 0; if (n <= 0)
return 0;
vector<int> nums(n); vector<int> nums(n);
cout << "递归 n = " << n << " 中的 nums 长度 = " << nums.size() << endl; cout << "递归 n = " << n << " 中的 nums 长度 = " << nums.size() << endl;
return quadraticRecur(n - 1); return quadraticRecur(n - 1);
} }
/* 指数阶(建立满二叉树) */ /* 指数阶(建立满二叉树) */
TreeNode* buildTree(int n) { TreeNode *buildTree(int n) {
if (n == 0) return nullptr; if (n == 0)
TreeNode* root = new TreeNode(0); return nullptr;
TreeNode *root = new TreeNode(0);
root->left = buildTree(n - 1); root->left = buildTree(n - 1);
root->right = buildTree(n - 1); root->right = buildTree(n - 1);
return root; return root;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
int n = 5; int n = 5;
@ -95,8 +97,8 @@ int main() {
quadratic(n); quadratic(n);
quadraticRecur(n); quadraticRecur(n);
// 指数阶 // 指数阶
TreeNode* root = buildTree(n); TreeNode *root = buildTree(n);
PrintUtil::printTree(root); printTree(root);
// 释放内存 // 释放内存
freeMemoryTree(root); freeMemoryTree(root);

View File

@ -24,7 +24,7 @@ int linear(int n) {
} }
/* 线性阶(遍历数组) */ /* 线性阶(遍历数组) */
int arrayTraversal(vector<int>& nums) { int arrayTraversal(vector<int> &nums) {
int count = 0; int count = 0;
// 循环次数与数组长度成正比 // 循环次数与数组长度成正比
for (int num : nums) { for (int num : nums) {
@ -46,8 +46,8 @@ int quadratic(int n) {
} }
/* 平方阶(冒泡排序) */ /* 平方阶(冒泡排序) */
int bubbleSort(vector<int>& nums) { int bubbleSort(vector<int> &nums) {
int count = 0; // 计数器 int count = 0; // 计数器
// 外循环:待排序元素数量为 n-1, n-2, ..., 1 // 外循环:待排序元素数量为 n-1, n-2, ..., 1
for (int i = nums.size() - 1; i > 0; i--) { for (int i = nums.size() - 1; i > 0; i--) {
// 内循环:冒泡操作 // 内循环:冒泡操作
@ -57,7 +57,7 @@ int bubbleSort(vector<int>& nums) {
int tmp = nums[j]; int tmp = nums[j];
nums[j] = nums[j + 1]; nums[j] = nums[j + 1];
nums[j + 1] = tmp; nums[j + 1] = tmp;
count += 3; // 元素交换包含 3 个单元操作 count += 3; // 元素交换包含 3 个单元操作
} }
} }
} }
@ -80,7 +80,8 @@ int exponential(int n) {
/* 指数阶(递归实现) */ /* 指数阶(递归实现) */
int expRecur(int n) { int expRecur(int n) {
if (n == 1) return 1; if (n == 1)
return 1;
return expRecur(n - 1) + expRecur(n - 1) + 1; return expRecur(n - 1) + expRecur(n - 1) + 1;
} }
@ -96,15 +97,16 @@ int logarithmic(float n) {
/* 对数阶(递归实现) */ /* 对数阶(递归实现) */
int logRecur(float n) { int logRecur(float n) {
if (n <= 1) return 0; if (n <= 1)
return 0;
return logRecur(n / 2) + 1; return logRecur(n / 2) + 1;
} }
/* 线性对数阶 */ /* 线性对数阶 */
int linearLogRecur(float n) { int linearLogRecur(float n) {
if (n <= 1) return 1; if (n <= 1)
int count = linearLogRecur(n / 2) + return 1;
linearLogRecur(n / 2); int count = linearLogRecur(n / 2) + linearLogRecur(n / 2);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
count++; count++;
} }
@ -113,7 +115,8 @@ int linearLogRecur(float n) {
/* 阶乘阶(递归实现) */ /* 阶乘阶(递归实现) */
int factorialRecur(int n) { int factorialRecur(int n) {
if (n == 0) return 1; if (n == 0)
return 1;
int count = 0; int count = 0;
// 从 1 个分裂出 n 个 // 从 1 个分裂出 n 个
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
@ -122,7 +125,6 @@ int factorialRecur(int n) {
return count; return count;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
// 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势 // 可以修改 n 运行,体会一下各种复杂度的操作数量变化趋势
@ -142,7 +144,7 @@ int main() {
cout << "平方阶的计算操作数量 = " << count << endl; cout << "平方阶的计算操作数量 = " << count << endl;
vector<int> nums(n); vector<int> nums(n);
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
nums[i] = n - i; // [n,n-1,...,2,1] nums[i] = n - i; // [n,n-1,...,2,1]
count = bubbleSort(nums); count = bubbleSort(nums);
cout << "平方阶(冒泡排序)的计算操作数量 = " << count << endl; cout << "平方阶(冒泡排序)的计算操作数量 = " << count << endl;
@ -151,12 +153,12 @@ int main() {
count = expRecur(n); count = expRecur(n);
cout << "指数阶(递归实现)的计算操作数量 = " << count << endl; cout << "指数阶(递归实现)的计算操作数量 = " << count << endl;
count = logarithmic((float) n); count = logarithmic((float)n);
cout << "对数阶(循环实现)的计算操作数量 = " << count << endl; cout << "对数阶(循环实现)的计算操作数量 = " << count << endl;
count = logRecur((float) n); count = logRecur((float)n);
cout << "对数阶(递归实现)的计算操作数量 = " << count << endl; cout << "对数阶(递归实现)的计算操作数量 = " << count << endl;
count = linearLogRecur((float) n); count = linearLogRecur((float)n);
cout << "线性对数阶(递归实现)的计算操作数量 = " << count << endl; cout << "线性对数阶(递归实现)的计算操作数量 = " << count << endl;
count = factorialRecur(n); count = factorialRecur(n);

View File

@ -21,7 +21,7 @@ vector<int> randomNumbers(int n) {
} }
/* 查找数组 nums 中数字 1 所在索引 */ /* 查找数组 nums 中数字 1 所在索引 */
int findOne(vector<int>& nums) { int findOne(vector<int> &nums) {
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
// 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1)
// 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n)
@ -31,7 +31,6 @@ int findOne(vector<int>& nums) {
return -1; return -1;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
@ -39,7 +38,7 @@ int main() {
vector<int> nums = randomNumbers(n); vector<int> nums = randomNumbers(n);
int index = findOne(nums); int index = findOne(nums);
cout << "\n数组 [ 1, 2, ..., n ] 被打乱后 = "; cout << "\n数组 [ 1, 2, ..., n ] 被打乱后 = ";
PrintUtil::printVector(nums); printVector(nums);
cout << "数字 1 的索引为 " << index << endl; cout << "数字 1 的索引为 " << index << endl;
} }
return 0; return 0;

View File

@ -7,19 +7,15 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 基于邻接表实现的无向图类 */ /* 基于邻接表实现的无向图类 */
class GraphAdjList class GraphAdjList {
{ public:
public:
// 邻接表key: 顶点value该顶点的所有邻接顶点 // 邻接表key: 顶点value该顶点的所有邻接顶点
unordered_map<Vertex *, vector<Vertex *>> adjList; unordered_map<Vertex *, vector<Vertex *>> adjList;
/* 在 vector 中删除指定节点 */ /* 在 vector 中删除指定节点 */
void remove(vector<Vertex *> &vec, Vertex *vet) void remove(vector<Vertex *> &vec, Vertex *vet) {
{ for (int i = 0; i < vec.size(); i++) {
for (int i = 0; i < vec.size(); i++) if (vec[i] == vet) {
{
if (vec[i] == vet)
{
vec.erase(vec.begin() + i); vec.erase(vec.begin() + i);
break; break;
} }
@ -27,11 +23,9 @@ public:
} }
/* 构造方法 */ /* 构造方法 */
GraphAdjList(const vector<vector<Vertex *>> &edges) GraphAdjList(const vector<vector<Vertex *>> &edges) {
{
// 添加所有顶点和边 // 添加所有顶点和边
for (const vector<Vertex *> &edge : edges) for (const vector<Vertex *> &edge : edges) {
{
addVertex(edge[0]); addVertex(edge[0]);
addVertex(edge[1]); addVertex(edge[1]);
addEdge(edge[0], edge[1]); addEdge(edge[0], edge[1]);
@ -39,11 +33,12 @@ public:
} }
/* 获取顶点数量 */ /* 获取顶点数量 */
int size() { return adjList.size(); } int size() {
return adjList.size();
}
/* 添加边 */ /* 添加边 */
void addEdge(Vertex *vet1, Vertex *vet2) void addEdge(Vertex *vet1, Vertex *vet2) {
{
if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2) if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)
throw invalid_argument("不存在顶点"); throw invalid_argument("不存在顶点");
// 添加边 vet1 - vet2 // 添加边 vet1 - vet2
@ -52,8 +47,7 @@ public:
} }
/* 删除边 */ /* 删除边 */
void removeEdge(Vertex *vet1, Vertex *vet2) void removeEdge(Vertex *vet1, Vertex *vet2) {
{
if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2) if (!adjList.count(vet1) || !adjList.count(vet2) || vet1 == vet2)
throw invalid_argument("不存在顶点"); throw invalid_argument("不存在顶点");
// 删除边 vet1 - vet2 // 删除边 vet1 - vet2
@ -62,8 +56,7 @@ public:
} }
/* 添加顶点 */ /* 添加顶点 */
void addVertex(Vertex *vet) void addVertex(Vertex *vet) {
{
if (adjList.count(vet)) if (adjList.count(vet))
return; return;
// 在邻接表中添加一个新链表 // 在邻接表中添加一个新链表
@ -71,29 +64,25 @@ public:
} }
/* 删除顶点 */ /* 删除顶点 */
void removeVertex(Vertex *vet) void removeVertex(Vertex *vet) {
{
if (!adjList.count(vet)) if (!adjList.count(vet))
throw invalid_argument("不存在顶点"); throw invalid_argument("不存在顶点");
// 在邻接表中删除顶点 vet 对应的链表 // 在邻接表中删除顶点 vet 对应的链表
adjList.erase(vet); adjList.erase(vet);
// 遍历其他顶点的链表,删除所有包含 vet 的边 // 遍历其他顶点的链表,删除所有包含 vet 的边
for (auto &[key, vec] : adjList) for (auto &adj : adjList) {
{ remove(adj.second, vet);
remove(vec, vet);
} }
} }
/* 打印邻接表 */ /* 打印邻接表 */
void print() void print() {
{
cout << "邻接表 =" << endl; cout << "邻接表 =" << endl;
for (auto &adj : adjList) for (auto &adj : adjList) {
{
const auto &key = adj.first; const auto &key = adj.first;
const auto &vec = adj.second; const auto &vec = adj.second;
cout << key->val << ": "; cout << key->val << ": ";
PrintUtil::printVector(vetsToVals(vec)); printVector(vetsToVals(vec));
} }
} }
}; };

View File

@ -9,9 +9,9 @@
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化无向图 */ /* 初始化无向图 */
vector<Vertex*> v = valsToVets(vector<int> { 1, 3, 2, 5, 4 }); vector<Vertex *> v = valsToVets(vector<int>{1, 3, 2, 5, 4});
vector<vector<Vertex*>> edges = { { v[0], v[1] }, { v[0], v[3] }, { v[1], v[2] }, vector<vector<Vertex *>> edges = {{v[0], v[1]}, {v[0], v[3]}, {v[1], v[2]},
{ v[2], v[3] }, { v[2], v[4] }, { v[3], v[4] } }; {v[2], v[3]}, {v[2], v[4]}, {v[3], v[4]}};
GraphAdjList graph(edges); GraphAdjList graph(edges);
cout << "\n初始化后,图为" << endl; cout << "\n初始化后,图为" << endl;
graph.print(); graph.print();
@ -29,7 +29,7 @@ int main() {
graph.print(); graph.print();
/* 添加顶点 */ /* 添加顶点 */
Vertex* v5 = new Vertex(6); Vertex *v5 = new Vertex(6);
graph.addVertex(v5); graph.addVertex(v5);
cout << "\n添加顶点 6 后,图为" << endl; cout << "\n添加顶点 6 后,图为" << endl;
graph.print(); graph.print();

View File

@ -11,16 +11,16 @@ class GraphAdjMat {
vector<int> vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” vector<int> vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引”
vector<vector<int>> adjMat; // 邻接矩阵,行列索引对应“顶点索引” vector<vector<int>> adjMat; // 邻接矩阵,行列索引对应“顶点索引”
public: public:
/* 构造方法 */ /* 构造方法 */
GraphAdjMat(const vector<int>& vertices, const vector<vector<int>>& edges) { GraphAdjMat(const vector<int> &vertices, const vector<vector<int>> &edges) {
// 添加顶点 // 添加顶点
for (int val : vertices) { for (int val : vertices) {
addVertex(val); addVertex(val);
} }
// 添加边 // 添加边
// 请注意edges 元素代表顶点索引,即对应 vertices 元素索引 // 请注意edges 元素代表顶点索引,即对应 vertices 元素索引
for (const vector<int>& edge : edges) { for (const vector<int> &edge : edges) {
addEdge(edge[0], edge[1]); addEdge(edge[0], edge[1]);
} }
} }
@ -38,7 +38,7 @@ public:
// 在邻接矩阵中添加一行 // 在邻接矩阵中添加一行
adjMat.emplace_back(n, 0); adjMat.emplace_back(n, 0);
// 在邻接矩阵中添加一列 // 在邻接矩阵中添加一列
for (vector<int>& row : adjMat) { for (vector<int> &row : adjMat) {
row.push_back(0); row.push_back(0);
} }
} }
@ -53,7 +53,7 @@ public:
// 在邻接矩阵中删除索引 index 的行 // 在邻接矩阵中删除索引 index 的行
adjMat.erase(adjMat.begin() + index); adjMat.erase(adjMat.begin() + index);
// 在邻接矩阵中删除索引 index 的列 // 在邻接矩阵中删除索引 index 的列
for (vector<int>& row : adjMat) { for (vector<int> &row : adjMat) {
row.erase(row.begin() + index); row.erase(row.begin() + index);
} }
} }
@ -84,9 +84,9 @@ public:
/* 打印邻接矩阵 */ /* 打印邻接矩阵 */
void print() { void print() {
cout << "顶点列表 = "; cout << "顶点列表 = ";
PrintUtil::printVector(vertices); printVector(vertices);
cout << "邻接矩阵 =" << endl; cout << "邻接矩阵 =" << endl;
PrintUtil::printVectorMatrix(adjMat); printVectorMatrix(adjMat);
} }
}; };
@ -94,8 +94,8 @@ public:
int main() { int main() {
/* 初始化无向图 */ /* 初始化无向图 */
// 请注意edges 元素代表顶点索引,即对应 vertices 元素索引 // 请注意edges 元素代表顶点索引,即对应 vertices 元素索引
vector<int> vertices = { 1, 3, 2, 5, 4 }; vector<int> vertices = {1, 3, 2, 5, 4};
vector<vector<int>> edges = { { 0, 1 }, { 0, 3 }, { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 4 } }; vector<vector<int>> edges = {{0, 1}, {0, 3}, {1, 2}, {2, 3}, {2, 4}, {3, 4}};
GraphAdjMat graph(vertices, edges); GraphAdjMat graph(vertices, edges);
cout << "\n初始化后,图为" << endl; cout << "\n初始化后,图为" << endl;
graph.print(); graph.print();

View File

@ -9,13 +9,13 @@
/* 广度优先遍历 BFS */ /* 广度优先遍历 BFS */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
vector<Vertex*> graphBFS(GraphAdjList &graph, Vertex *startVet) { vector<Vertex *> graphBFS(GraphAdjList &graph, Vertex *startVet) {
// 顶点遍历序列 // 顶点遍历序列
vector<Vertex*> res; vector<Vertex *> res;
// 哈希表,用于记录已被访问过的顶点 // 哈希表,用于记录已被访问过的顶点
unordered_set<Vertex*> visited = { startVet }; unordered_set<Vertex *> visited = {startVet};
// 队列用于实现 BFS // 队列用于实现 BFS
queue<Vertex*> que; queue<Vertex *> que;
que.push(startVet); que.push(startVet);
// 以顶点 vet 为起点,循环直至访问完所有顶点 // 以顶点 vet 为起点,循环直至访问完所有顶点
while (!que.empty()) { while (!que.empty()) {
@ -25,8 +25,8 @@ vector<Vertex*> graphBFS(GraphAdjList &graph, Vertex *startVet) {
// 遍历该顶点的所有邻接顶点 // 遍历该顶点的所有邻接顶点
for (auto adjVet : graph.adjList[vet]) { for (auto adjVet : graph.adjList[vet]) {
if (visited.count(adjVet)) if (visited.count(adjVet))
continue; // 跳过已被访问过的顶点 continue; // 跳过已被访问过的顶点
que.push(adjVet); // 只入队未访问的顶点 que.push(adjVet); // 只入队未访问的顶点
visited.emplace(adjVet); // 标记该顶点已被访问 visited.emplace(adjVet); // 标记该顶点已被访问
} }
} }
@ -37,18 +37,18 @@ vector<Vertex*> graphBFS(GraphAdjList &graph, Vertex *startVet) {
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化无向图 */ /* 初始化无向图 */
vector<Vertex*> v = valsToVets({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); vector<Vertex *> v = valsToVets({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
vector<vector<Vertex*>> edges = { { v[0], v[1] }, { v[0], v[3] }, { v[1], v[2] }, { v[1], v[4] }, vector<vector<Vertex *>> edges = {{v[0], v[1]}, {v[0], v[3]}, {v[1], v[2]}, {v[1], v[4]},
{ v[2], v[5] }, { v[3], v[4] }, { v[3], v[6] }, { v[4], v[5] }, {v[2], v[5]}, {v[3], v[4]}, {v[3], v[6]}, {v[4], v[5]},
{ v[4], v[7] }, { v[5], v[8] }, { v[6], v[7] }, { v[7], v[8] } }; {v[4], v[7]}, {v[5], v[8]}, {v[6], v[7]}, {v[7], v[8]}};
GraphAdjList graph(edges); GraphAdjList graph(edges);
cout << "\n初始化后,图为\\n"; cout << "\n初始化后,图为\\n";
graph.print(); graph.print();
/* 广度优先遍历 BFS */ /* 广度优先遍历 BFS */
vector<Vertex*> res = graphBFS(graph, v[0]); vector<Vertex *> res = graphBFS(graph, v[0]);
cout << "\n广度优先遍历BFS顶点序列为" << endl; cout << "\n广度优先遍历BFS顶点序列为" << endl;
PrintUtil::printVector(vetsToVals(res)); printVector(vetsToVals(res));
// 释放内存 // 释放内存
for (Vertex *vet : v) { for (Vertex *vet : v) {

View File

@ -8,13 +8,13 @@
#include "./graph_adjacency_list.cpp" #include "./graph_adjacency_list.cpp"
/* 深度优先遍历 DFS 辅助函数 */ /* 深度优先遍历 DFS 辅助函数 */
void dfs(GraphAdjList& graph, unordered_set<Vertex*>& visited, vector<Vertex*>& res, Vertex* vet) { void dfs(GraphAdjList &graph, unordered_set<Vertex *> &visited, vector<Vertex *> &res, Vertex *vet) {
res.push_back(vet); // 记录访问顶点 res.push_back(vet); // 记录访问顶点
visited.emplace(vet); // 标记该顶点已被访问 visited.emplace(vet); // 标记该顶点已被访问
// 遍历该顶点的所有邻接顶点 // 遍历该顶点的所有邻接顶点
for (Vertex* adjVet : graph.adjList[vet]) { for (Vertex *adjVet : graph.adjList[vet]) {
if (visited.count(adjVet)) if (visited.count(adjVet))
continue; // 跳过已被访问过的顶点 continue; // 跳过已被访问过的顶点
// 递归访问邻接顶点 // 递归访问邻接顶点
dfs(graph, visited, res, adjVet); dfs(graph, visited, res, adjVet);
} }
@ -22,11 +22,11 @@ void dfs(GraphAdjList& graph, unordered_set<Vertex*>& visited, vector<Vertex*>&
/* 深度优先遍历 DFS */ /* 深度优先遍历 DFS */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
vector<Vertex*> graphDFS(GraphAdjList& graph, Vertex* startVet) { vector<Vertex *> graphDFS(GraphAdjList &graph, Vertex *startVet) {
// 顶点遍历序列 // 顶点遍历序列
vector<Vertex*> res; vector<Vertex *> res;
// 哈希表,用于记录已被访问过的顶点 // 哈希表,用于记录已被访问过的顶点
unordered_set<Vertex*> visited; unordered_set<Vertex *> visited;
dfs(graph, visited, res, startVet); dfs(graph, visited, res, startVet);
return res; return res;
} }
@ -34,17 +34,17 @@ vector<Vertex*> graphDFS(GraphAdjList& graph, Vertex* startVet) {
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化无向图 */ /* 初始化无向图 */
vector<Vertex*> v = valsToVets(vector<int> { 0, 1, 2, 3, 4, 5, 6 }); vector<Vertex *> v = valsToVets(vector<int>{0, 1, 2, 3, 4, 5, 6});
vector<vector<Vertex*>> edges = { { v[0], v[1] }, { v[0], v[3] }, { v[1], v[2] }, vector<vector<Vertex *>> edges = {{v[0], v[1]}, {v[0], v[3]}, {v[1], v[2]},
{ v[2], v[5] }, { v[4], v[5] }, { v[5], v[6] } }; {v[2], v[5]}, {v[4], v[5]}, {v[5], v[6]}};
GraphAdjList graph(edges); GraphAdjList graph(edges);
cout << "\n初始化后,图为" << endl; cout << "\n初始化后,图为" << endl;
graph.print(); graph.print();
/* 深度优先遍历 DFS */ /* 深度优先遍历 DFS */
vector<Vertex*> res = graphDFS(graph, v[0]); vector<Vertex *> res = graphDFS(graph, v[0]);
cout << "\n深度优先遍历DFS顶点序列为" << endl; cout << "\n深度优先遍历DFS顶点序列为" << endl;
PrintUtil::printVector(vetsToVals(res)); printVector(vetsToVals(res));
// 释放内存 // 释放内存
for (Vertex *vet : v) { for (Vertex *vet : v) {

View File

@ -8,7 +8,7 @@
/* 键值对 int->String */ /* 键值对 int->String */
struct Entry { struct Entry {
public: public:
int key; int key;
string val; string val;
Entry(int key, string val) { Entry(int key, string val) {
@ -19,12 +19,13 @@ public:
/* 基于数组简易实现的哈希表 */ /* 基于数组简易实现的哈希表 */
class ArrayHashMap { class ArrayHashMap {
private: private:
vector<Entry*> buckets; vector<Entry *> buckets;
public:
public:
ArrayHashMap() { ArrayHashMap() {
// 初始化数组,包含 100 个桶 // 初始化数组,包含 100 个桶
buckets = vector<Entry*>(100); buckets = vector<Entry *>(100);
} }
/* 哈希函数 */ /* 哈希函数 */
@ -36,7 +37,7 @@ public:
/* 查询操作 */ /* 查询操作 */
string get(int key) { string get(int key) {
int index = hashFunc(key); int index = hashFunc(key);
Entry* pair = buckets[index]; Entry *pair = buckets[index];
if (pair == nullptr) if (pair == nullptr)
return nullptr; return nullptr;
return pair->val; return pair->val;
@ -44,7 +45,7 @@ public:
/* 添加操作 */ /* 添加操作 */
void put(int key, string val) { void put(int key, string val) {
Entry* pair = new Entry(key, val); Entry *pair = new Entry(key, val);
int index = hashFunc(key); int index = hashFunc(key);
buckets[index] = pair; buckets[index] = pair;
} }
@ -57,9 +58,9 @@ public:
} }
/* 获取所有键值对 */ /* 获取所有键值对 */
vector<Entry*> entrySet() { vector<Entry *> entrySet() {
vector<Entry*> entrySet; vector<Entry *> entrySet;
for (Entry* pair: buckets) { for (Entry *pair : buckets) {
if (pair != nullptr) { if (pair != nullptr) {
entrySet.push_back(pair); entrySet.push_back(pair);
} }
@ -70,7 +71,7 @@ public:
/* 获取所有键 */ /* 获取所有键 */
vector<int> keySet() { vector<int> keySet() {
vector<int> keySet; vector<int> keySet;
for (Entry* pair: buckets) { for (Entry *pair : buckets) {
if (pair != nullptr) { if (pair != nullptr) {
keySet.push_back(pair->key); keySet.push_back(pair->key);
} }
@ -81,8 +82,8 @@ public:
/* 获取所有值 */ /* 获取所有值 */
vector<string> valueSet() { vector<string> valueSet() {
vector<string> valueSet; vector<string> valueSet;
for (Entry* pair: buckets) { for (Entry *pair : buckets) {
if (pair != nullptr){ if (pair != nullptr) {
valueSet.push_back(pair->val); valueSet.push_back(pair->val);
} }
} }
@ -91,7 +92,7 @@ public:
/* 打印哈希表 */ /* 打印哈希表 */
void print() { void print() {
for (Entry* kv: entrySet()) { for (Entry *kv : entrySet()) {
cout << kv->key << " -> " << kv->val << endl; cout << kv->key << " -> " << kv->val << endl;
} }
} }
@ -125,17 +126,17 @@ int main() {
/* 遍历哈希表 */ /* 遍历哈希表 */
cout << "\n遍历键值对 Key->Value" << endl; cout << "\n遍历键值对 Key->Value" << endl;
for (auto kv: map.entrySet()) { for (auto kv : map.entrySet()) {
cout << kv->key << " -> " << kv->val << endl; cout << kv->key << " -> " << kv->val << endl;
} }
cout << "\n单独遍历键 Key" << endl; cout << "\n单独遍历键 Key" << endl;
for (auto key: map.keySet()) { for (auto key : map.keySet()) {
cout << key << endl; cout << key << endl;
} }
cout << "\n单独遍历值 Value" << endl; cout << "\n单独遍历值 Value" << endl;
for (auto val: map.valueSet()) { for (auto val : map.valueSet()) {
cout << val << endl; cout << val << endl;
} }

View File

@ -6,7 +6,6 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化哈希表 */ /* 初始化哈希表 */
@ -20,7 +19,7 @@ int main() {
map[13276] = "小法"; map[13276] = "小法";
map[10583] = "小鸭"; map[10583] = "小鸭";
cout << "\n添加完成后,哈希表为\nKey -> Value" << endl; cout << "\n添加完成后,哈希表为\nKey -> Value" << endl;
PrintUtil::printHashMap(map); printHashMap(map);
/* 查询操作 */ /* 查询操作 */
// 向哈希表输入键 key ,得到值 value // 向哈希表输入键 key ,得到值 value
@ -31,21 +30,21 @@ int main() {
// 在哈希表中删除键值对 (key, value) // 在哈希表中删除键值对 (key, value)
map.erase(10583); map.erase(10583);
cout << "\n删除 10583 后,哈希表为\nKey -> Value" << endl; cout << "\n删除 10583 后,哈希表为\nKey -> Value" << endl;
PrintUtil::printHashMap(map); printHashMap(map);
/* 遍历哈希表 */ /* 遍历哈希表 */
cout << "\n遍历键值对 Key->Value" << endl; cout << "\n遍历键值对 Key->Value" << endl;
for (auto kv: map) { for (auto kv : map) {
cout << kv.first << " -> " << kv.second << endl; cout << kv.first << " -> " << kv.second << endl;
} }
cout << "\n单独遍历键 Key" << endl; cout << "\n单独遍历键 Key" << endl;
for (auto key: map) { for (auto key : map) {
cout << key.first << endl; cout << key.first << endl;
} }
cout << "\n单独遍历值 Value" << endl; cout << "\n单独遍历值 Value" << endl;
for (auto val: map) { for (auto val : map) {
cout << val.second << endl; cout << val.second << endl;
} }

View File

@ -6,23 +6,20 @@
#include "../include/include.hpp" #include "../include/include.hpp"
void testPush(priority_queue<int> &heap, int val) void testPush(priority_queue<int> &heap, int val) {
{
heap.push(val); // 元素入堆 heap.push(val); // 元素入堆
cout << "\n元素 " << val << " 入堆后" << endl; cout << "\n元素 " << val << " 入堆后" << endl;
PrintUtil::printHeap(heap); printHeap(heap);
} }
void testPop(priority_queue<int> &heap) void testPop(priority_queue<int> &heap) {
{
int val = heap.top(); int val = heap.top();
heap.pop(); heap.pop();
cout << "\n堆顶元素 " << val << " 出堆后" << endl; cout << "\n堆顶元素 " << val << " 出堆后" << endl;
PrintUtil::printHeap(heap); printHeap(heap);
} }
int main() int main() {
{
/* 初始化堆 */ /* 初始化堆 */
// 初始化小顶堆 // 初始化小顶堆
// priority_queue<int, vector<int>, greater<int>> minHeap; // priority_queue<int, vector<int>, greater<int>> minHeap;
@ -62,6 +59,6 @@ int main()
vector<int> input{1, 3, 2, 5, 4}; vector<int> input{1, 3, 2, 5, 4};
priority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end()); priority_queue<int, vector<int>, greater<int>> minHeap(input.begin(), input.end());
cout << "输入列表并建立小顶堆后" << endl; cout << "输入列表并建立小顶堆后" << endl;
PrintUtil::printHeap(minHeap); printHeap(minHeap);
return 0; return 0;
} }

View File

@ -8,7 +8,7 @@
/* 大顶堆 */ /* 大顶堆 */
class MaxHeap { class MaxHeap {
private: private:
// 使用动态数组,这样无需考虑扩容问题 // 使用动态数组,这样无需考虑扩容问题
vector<int> maxHeap; vector<int> maxHeap;
@ -20,7 +20,7 @@ private:
/* 获取右子节点索引 */ /* 获取右子节点索引 */
int right(int i) { int right(int i) {
return 2 * i + 2; return 2 * i + 2;
} }
/* 获取父节点索引 */ /* 获取父节点索引 */
int parent(int i) { int parent(int i) {
@ -31,7 +31,7 @@ private:
void siftUp(int i) { void siftUp(int i) {
while (true) { while (true) {
// 获取节点 i 的父节点 // 获取节点 i 的父节点
int p = parent(i); int p = parent(i);
// 当“越过根节点”或“节点无需修复”时,结束堆化 // 当“越过根节点”或“节点无需修复”时,结束堆化
if (p < 0 || maxHeap[i] <= maxHeap[p]) if (p < 0 || maxHeap[i] <= maxHeap[p])
break; break;
@ -48,12 +48,12 @@ private:
// 判断节点 i, l, r 中值最大的节点,记为 ma // 判断节点 i, l, r 中值最大的节点,记为 ma
int l = left(i), r = right(i), ma = i; int l = left(i), r = right(i), ma = i;
// 若节点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 // 若节点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
if (l < size() && maxHeap[l] > maxHeap[ma]) if (l < size() && maxHeap[l] > maxHeap[ma])
ma = l; ma = l;
if (r < size() && maxHeap[r] > maxHeap[ma]) if (r < size() && maxHeap[r] > maxHeap[ma])
ma = r; ma = r;
// 若节点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 // 若节点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
if (ma == i) if (ma == i)
break; break;
swap(maxHeap[i], maxHeap[ma]); swap(maxHeap[i], maxHeap[ma]);
// 循环向下堆化 // 循环向下堆化
@ -61,7 +61,7 @@ private:
} }
} }
public: public:
/* 构造方法,根据输入列表建堆 */ /* 构造方法,根据输入列表建堆 */
MaxHeap(vector<int> nums) { MaxHeap(vector<int> nums) {
// 将列表元素原封不动添加进堆 // 将列表元素原封不动添加进堆
@ -112,15 +112,14 @@ public:
/* 打印堆(二叉树)*/ /* 打印堆(二叉树)*/
void print() { void print() {
cout << "堆的数组表示:"; cout << "堆的数组表示:";
PrintUtil::printVector(maxHeap); printVector(maxHeap);
cout << "堆的树状表示:" << endl; cout << "堆的树状表示:" << endl;
TreeNode *root = vecToTree(maxHeap); TreeNode *root = vecToTree(maxHeap);
PrintUtil::printTree(root); printTree(root);
freeMemoryTree(root); freeMemoryTree(root);
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化大顶堆 */ /* 初始化大顶堆 */

View File

@ -7,17 +7,17 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 二分查找(双闭区间) */ /* 二分查找(双闭区间) */
int binarySearch(vector<int>& nums, int target) { int binarySearch(vector<int> &nums, int target) {
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
int i = 0, j = nums.size() - 1; int i = 0, j = nums.size() - 1;
// 循环,当搜索区间为空时跳出(当 i > j 时为空) // 循环,当搜索区间为空时跳出(当 i > j 时为空)
while (i <= j) { while (i <= j) {
int m = (i + j) / 2; // 计算中点索引 m int m = (i + j) / 2; // 计算中点索引 m
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中
i = m + 1; i = m + 1;
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中 else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
j = m - 1; j = m - 1;
else // 找到目标元素,返回其索引 else // 找到目标元素,返回其索引
return m; return m;
} }
// 未找到目标元素,返回 -1 // 未找到目标元素,返回 -1
@ -25,29 +25,28 @@ int binarySearch(vector<int>& nums, int target) {
} }
/* 二分查找(左闭右开) */ /* 二分查找(左闭右开) */
int binarySearch1(vector<int>& nums, int target) { int binarySearch1(vector<int> &nums, int target) {
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
int i = 0, j = nums.size(); int i = 0, j = nums.size();
// 循环,当搜索区间为空时跳出(当 i = j 时为空) // 循环,当搜索区间为空时跳出(当 i = j 时为空)
while (i < j) { while (i < j) {
int m = (i + j) / 2; // 计算中点索引 m int m = (i + j) / 2; // 计算中点索引 m
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中
i = m + 1; i = m + 1;
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
j = m; j = m;
else // 找到目标元素,返回其索引 else // 找到目标元素,返回其索引
return m; return m;
} }
// 未找到目标元素,返回 -1 // 未找到目标元素,返回 -1
return -1; return -1;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
int target = 6; int target = 6;
vector<int> nums = { 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 }; vector<int> nums = {1, 3, 6, 8, 12, 15, 23, 67, 70, 92};
/* 二分查找(双闭区间) */ /* 二分查找(双闭区间) */
int index = binarySearch(nums, target); int index = binarySearch(nums, target);
cout << "目标元素 6 的索引 = " << index << endl; cout << "目标元素 6 的索引 = " << index << endl;
@ -55,6 +54,6 @@ int main() {
/* 二分查找(左闭右开) */ /* 二分查找(左闭右开) */
index = binarySearch1(nums, target); index = binarySearch1(nums, target);
cout << "目标元素 6 的索引 = " << index << endl; cout << "目标元素 6 的索引 = " << index << endl;
return 0; return 0;
} }

View File

@ -16,7 +16,7 @@ int hashingSearchArray(unordered_map<int, int> map, int target) {
} }
/* 哈希查找(链表) */ /* 哈希查找(链表) */
ListNode* hashingSearchLinkedList(unordered_map<int, ListNode*> map, int target) { ListNode *hashingSearchLinkedList(unordered_map<int, ListNode *> map, int target) {
// 哈希表的 key: 目标节点值value: 节点对象 // 哈希表的 key: 目标节点值value: 节点对象
// 若哈希表中无此 key ,返回 nullptr // 若哈希表中无此 key ,返回 nullptr
if (map.find(target) == map.end()) if (map.find(target) == map.end())
@ -24,30 +24,29 @@ ListNode* hashingSearchLinkedList(unordered_map<int, ListNode*> map, int target)
return map[target]; return map[target];
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
int target = 3; int target = 3;
/* 哈希查找(数组) */ /* 哈希查找(数组) */
vector<int> nums = { 1, 5, 3, 2, 4, 7, 5, 9, 10, 8 }; vector<int> nums = {1, 5, 3, 2, 4, 7, 5, 9, 10, 8};
// 初始化哈希表 // 初始化哈希表
unordered_map<int, int> map; unordered_map<int, int> map;
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
map[nums[i]] = i; // key: 元素value: 索引 map[nums[i]] = i; // key: 元素value: 索引
} }
int index = hashingSearchArray(map, target); int index = hashingSearchArray(map, target);
cout << "目标元素 3 的索引 = " << index << endl; cout << "目标元素 3 的索引 = " << index << endl;
/* 哈希查找(链表) */ /* 哈希查找(链表) */
ListNode* head = vecToLinkedList(nums); ListNode *head = vecToLinkedList(nums);
// 初始化哈希表 // 初始化哈希表
unordered_map<int, ListNode*> map1; unordered_map<int, ListNode *> map1;
while (head != nullptr) { while (head != nullptr) {
map1[head->val] = head; // key: 节点值value: 节点 map1[head->val] = head; // key: 节点值value: 节点
head = head->next; head = head->next;
} }
ListNode* node = hashingSearchLinkedList(map1, target); ListNode *node = hashingSearchLinkedList(map1, target);
cout << "目标节点值 3 的对应节点对象为 " << node << endl; cout << "目标节点值 3 的对应节点对象为 " << node << endl;
return 0; return 0;

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 线性查找(数组) */ /* 线性查找(数组) */
int linearSearchArray(vector<int>& nums, int target) { int linearSearchArray(vector<int> &nums, int target) {
// 遍历数组 // 遍历数组
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
// 找到目标元素,返回其索引 // 找到目标元素,返回其索引
@ -19,7 +19,7 @@ int linearSearchArray(vector<int>& nums, int target) {
} }
/* 线性查找(链表) */ /* 线性查找(链表) */
ListNode* linearSearchLinkedList(ListNode* head, int target) { ListNode *linearSearchLinkedList(ListNode *head, int target) {
// 遍历链表 // 遍历链表
while (head != nullptr) { while (head != nullptr) {
// 找到目标节点,返回之 // 找到目标节点,返回之
@ -31,20 +31,19 @@ ListNode* linearSearchLinkedList(ListNode* head, int target) {
return nullptr; return nullptr;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
int target = 3; int target = 3;
/* 在数组中执行线性查找 */ /* 在数组中执行线性查找 */
vector<int> nums = { 1, 5, 3, 2, 4, 7, 5, 9, 10, 8 }; vector<int> nums = {1, 5, 3, 2, 4, 7, 5, 9, 10, 8};
int index = linearSearchArray(nums, target); int index = linearSearchArray(nums, target);
cout << "目标元素 3 的索引 = " << index << endl; cout << "目标元素 3 的索引 = " << index << endl;
/* 在链表中执行线性查找 */ /* 在链表中执行线性查找 */
ListNode* head = vecToLinkedList(nums); ListNode *head = vecToLinkedList(nums);
ListNode* node = linearSearchLinkedList(head, target); ListNode *node = linearSearchLinkedList(head, target);
cout << "目标节点值 3 的对应节点对象为 " << node << endl; cout << "目标节点值 3 的对应节点对象为 " << node << endl;
return 0; return 0;
} }

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 冒泡排序 */ /* 冒泡排序 */
void bubbleSort(vector<int>& nums) { void bubbleSort(vector<int> &nums) {
// 外循环:待排序元素数量为 n-1, n-2, ..., 1 // 外循环:待排序元素数量为 n-1, n-2, ..., 1
for (int i = nums.size() - 1; i > 0; i--) { for (int i = nums.size() - 1; i > 0; i--) {
// 内循环:冒泡操作 // 内循环:冒泡操作
@ -22,7 +22,7 @@ void bubbleSort(vector<int>& nums) {
} }
/* 冒泡排序(标志优化)*/ /* 冒泡排序(标志优化)*/
void bubbleSortWithFlag(vector<int>& nums) { void bubbleSortWithFlag(vector<int> &nums) {
// 外循环:待排序元素数量为 n-1, n-2, ..., 1 // 外循环:待排序元素数量为 n-1, n-2, ..., 1
for (int i = nums.size() - 1; i > 0; i--) { for (int i = nums.size() - 1; i > 0; i--) {
bool flag = false; // 初始化标志位 bool flag = false; // 初始化标志位
@ -32,25 +32,25 @@ void bubbleSortWithFlag(vector<int>& nums) {
// 交换 nums[j] 与 nums[j + 1] // 交换 nums[j] 与 nums[j + 1]
// 这里使用了 std::swap() 函数 // 这里使用了 std::swap() 函数
swap(nums[j], nums[j + 1]); swap(nums[j], nums[j + 1]);
flag = true; // 记录交换元素 flag = true; // 记录交换元素
} }
} }
if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出 if (!flag)
break; // 此轮冒泡未交换任何元素,直接跳出
} }
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
vector<int> nums = { 4, 1, 3, 1, 5, 2 }; vector<int> nums = {4, 1, 3, 1, 5, 2};
bubbleSort(nums); bubbleSort(nums);
cout << "冒泡排序完成后 nums = "; cout << "冒泡排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
vector<int> nums1 = { 4, 1, 3, 1, 5, 2 }; vector<int> nums1 = {4, 1, 3, 1, 5, 2};
bubbleSortWithFlag(nums1); bubbleSortWithFlag(nums1);
cout << "冒泡排序完成后 nums1 = "; cout << "冒泡排序完成后 nums1 = ";
PrintUtil::printVector(nums1); printVector(nums1);
return 0; return 0;
} }

View File

@ -7,44 +7,38 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 桶排序 */ /* 桶排序 */
void bucketSort(vector<float> &nums) void bucketSort(vector<float> &nums) {
{
// 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素
int k = nums.size() / 2; int k = nums.size() / 2;
vector<vector<float>> buckets(k); vector<vector<float>> buckets(k);
// 1. 将数组元素分配到各个桶中 // 1. 将数组元素分配到各个桶中
for (float num : nums) for (float num : nums) {
{
// 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
int i = num * k; int i = num * k;
// 将 num 添加进桶 bucket_idx // 将 num 添加进桶 bucket_idx
buckets[i].push_back(num); buckets[i].push_back(num);
} }
// 2. 对各个桶执行排序 // 2. 对各个桶执行排序
for (vector<float> &bucket : buckets) for (vector<float> &bucket : buckets) {
{
// 使用内置排序函数,也可以替换成其他排序算法 // 使用内置排序函数,也可以替换成其他排序算法
sort(bucket.begin(), bucket.end()); sort(bucket.begin(), bucket.end());
} }
// 3. 遍历桶合并结果 // 3. 遍历桶合并结果
int i = 0; int i = 0;
for (vector<float> &bucket : buckets) for (vector<float> &bucket : buckets) {
{ for (float num : bucket) {
for (float num : bucket)
{
nums[i++] = num; nums[i++] = num;
} }
} }
} }
/* Driver Code */ /* Driver Code */
int main() int main() {
{
// 设输入数据为浮点数,范围为 [0, 1) // 设输入数据为浮点数,范围为 [0, 1)
vector<float> nums = {0.49f, 0.96f, 0.82f, 0.09f, 0.57f, 0.43f, 0.91f, 0.75f, 0.15f, 0.37f}; vector<float> nums = {0.49f, 0.96f, 0.82f, 0.09f, 0.57f, 0.43f, 0.91f, 0.75f, 0.15f, 0.37f};
bucketSort(nums); bucketSort(nums);
cout << "桶排序完成后 nums = "; cout << "桶排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
return 0; return 0;
} }

View File

@ -8,7 +8,7 @@
/* 计数排序 */ /* 计数排序 */
// 简单实现,无法用于排序对象 // 简单实现,无法用于排序对象
void countingSortNaive(vector<int>& nums) { void countingSortNaive(vector<int> &nums) {
// 1. 统计数组最大元素 m // 1. 统计数组最大元素 m
int m = 0; int m = 0;
for (int num : nums) { for (int num : nums) {
@ -31,7 +31,7 @@ void countingSortNaive(vector<int>& nums) {
/* 计数排序 */ /* 计数排序 */
// 完整实现,可排序对象,并且是稳定排序 // 完整实现,可排序对象,并且是稳定排序
void countingSort(vector<int>& nums) { void countingSort(vector<int> &nums) {
// 1. 统计数组最大元素 m // 1. 统计数组最大元素 m
int m = 0; int m = 0;
for (int num : nums) { for (int num : nums) {
@ -55,7 +55,7 @@ void countingSort(vector<int>& nums) {
for (int i = n - 1; i >= 0; i--) { for (int i = n - 1; i >= 0; i--) {
int num = nums[i]; int num = nums[i];
res[counter[num] - 1] = num; // 将 num 放置到对应索引处 res[counter[num] - 1] = num; // 将 num 放置到对应索引处
counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引 counter[num]--; // 令前缀和自减 1 ,得到下次放置 num 的索引
} }
// 使用结果数组 res 覆盖原数组 nums // 使用结果数组 res 覆盖原数组 nums
nums = res; nums = res;
@ -63,15 +63,15 @@ void countingSort(vector<int>& nums) {
/* Driver Code */ /* Driver Code */
int main() { int main() {
vector<int> nums = { 1, 0, 1, 2, 0, 4, 0, 2, 2, 4 }; vector<int> nums = {1, 0, 1, 2, 0, 4, 0, 2, 2, 4};
countingSortNaive(nums); countingSortNaive(nums);
cout << "计数排序(无法排序对象)完成后 nums = "; cout << "计数排序(无法排序对象)完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
vector<int> nums1 = { 1, 0, 1, 2, 0, 4, 0, 2, 2, 4 }; vector<int> nums1 = {1, 0, 1, 2, 0, 4, 0, 2, 2, 4};
countingSort(nums1); countingSort(nums1);
cout << "计数排序完成后 nums1 = "; cout << "计数排序完成后 nums1 = ";
PrintUtil::printVector(nums1); printVector(nums1);
return 0; return 0;
} }

View File

@ -7,26 +7,25 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 插入排序 */ /* 插入排序 */
void insertionSort(vector<int>& nums) { void insertionSort(vector<int> &nums) {
// 外循环base = nums[1], nums[2], ..., nums[n-1] // 外循环base = nums[1], nums[2], ..., nums[n-1]
for (int i = 1; i < nums.size(); i++) { for (int i = 1; i < nums.size(); i++) {
int base = nums[i], j = i - 1; int base = nums[i], j = i - 1;
// 内循环:将 base 插入到左边的正确位置 // 内循环:将 base 插入到左边的正确位置
while (j >= 0 && nums[j] > base) { while (j >= 0 && nums[j] > base) {
nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位
j--; j--;
} }
nums[j + 1] = base; // 2. 将 base 赋值到正确位置 nums[j + 1] = base; // 2. 将 base 赋值到正确位置
} }
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
vector<int> nums = { 4, 1, 3, 1, 5, 2 }; vector<int> nums = {4, 1, 3, 1, 5, 2};
insertionSort(nums); insertionSort(nums);
cout << "插入排序完成后 nums = "; cout << "插入排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
return 0; return 0;
} }

View File

@ -9,15 +9,15 @@
/* 合并左子数组和右子数组 */ /* 合并左子数组和右子数组 */
// 左子数组区间 [left, mid] // 左子数组区间 [left, mid]
// 右子数组区间 [mid + 1, right] // 右子数组区间 [mid + 1, right]
void merge(vector<int>& nums, int left, int mid, int right) { void merge(vector<int> &nums, int left, int mid, int right) {
// 初始化辅助数组 // 初始化辅助数组
vector<int> tmp(nums.begin() + left, nums.begin() + right + 1); vector<int> tmp(nums.begin() + left, nums.begin() + right + 1);
// 左子数组的起始索引和结束索引 // 左子数组的起始索引和结束索引
int leftStart = left - left, leftEnd = mid - left; int leftStart = left - left, leftEnd = mid - left;
// 右子数组的起始索引和结束索引 // 右子数组的起始索引和结束索引
int rightStart = mid + 1 - left, rightEnd = right - left; int rightStart = mid + 1 - left, rightEnd = right - left;
// i, j 分别指向左子数组、右子数组的首元素 // i, j 分别指向左子数组、右子数组的首元素
int i = leftStart, j = rightStart; int i = leftStart, j = rightStart;
// 通过覆盖原数组 nums 来合并左子数组和右子数组 // 通过覆盖原数组 nums 来合并左子数组和右子数组
for (int k = left; k <= right; k++) { for (int k = left; k <= right; k++) {
// 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++ // 若“左子数组已全部合并完”,则选取右子数组元素,并且 j++
@ -33,9 +33,10 @@ void merge(vector<int>& nums, int left, int mid, int right) {
} }
/* 归并排序 */ /* 归并排序 */
void mergeSort(vector<int>& nums, int left, int right) { void mergeSort(vector<int> &nums, int left, int right) {
// 终止条件 // 终止条件
if (left >= right) return; // 当子数组长度为 1 时终止递归 if (left >= right)
return; // 当子数组长度为 1 时终止递归
// 划分阶段 // 划分阶段
int mid = (left + right) / 2; // 计算中点 int mid = (left + right) / 2; // 计算中点
mergeSort(nums, left, mid); // 递归左子数组 mergeSort(nums, left, mid); // 递归左子数组
@ -44,14 +45,13 @@ void mergeSort(vector<int>& nums, int left, int right) {
merge(nums, left, mid, right); merge(nums, left, mid, right);
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 归并排序 */ /* 归并排序 */
vector<int> nums = { 7, 3, 2, 6, 0, 1, 5, 4 }; vector<int> nums = {7, 3, 2, 6, 0, 1, 5, 4};
mergeSort(nums, 0, nums.size() - 1); mergeSort(nums, 0, nums.size() - 1);
cout << "归并排序完成后 nums = "; cout << "归并排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
return 0; return 0;
} }

View File

@ -8,32 +8,32 @@
/* 快速排序类 */ /* 快速排序类 */
class QuickSort { class QuickSort {
private: private:
/* 元素交换 */ /* 元素交换 */
static void swap(vector<int>& nums, int i, int j) { static void swap(vector<int> &nums, int i, int j) {
int tmp = nums[i]; int tmp = nums[i];
nums[i] = nums[j]; nums[i] = nums[j];
nums[j] = tmp; nums[j] = tmp;
} }
/* 哨兵划分 */ /* 哨兵划分 */
static int partition(vector<int>& nums, int left, int right) { static int partition(vector<int> &nums, int left, int right) {
// 以 nums[left] 作为基准数 // 以 nums[left] 作为基准数
int i = left, j = right; int i = left, j = right;
while (i < j) { while (i < j) {
while (i < j && nums[j] >= nums[left]) while (i < j && nums[j] >= nums[left])
j--; // 从右向左找首个小于基准数的元素 j--; // 从右向左找首个小于基准数的元素
while (i < j && nums[i] <= nums[left]) while (i < j && nums[i] <= nums[left])
i++; // 从左向右找首个大于基准数的元素 i++; // 从左向右找首个大于基准数的元素
swap(nums, i, j); // 交换这两个元素 swap(nums, i, j); // 交换这两个元素
} }
swap(nums, i, left); // 将基准数交换至两子数组的分界线 swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引 return i; // 返回基准数的索引
} }
public: public:
/* 快速排序 */ /* 快速排序 */
static void quickSort(vector<int>& nums, int left, int right) { static void quickSort(vector<int> &nums, int left, int right) {
// 子数组长度为 1 时终止递归 // 子数组长度为 1 时终止递归
if (left >= right) if (left >= right)
return; return;
@ -47,16 +47,16 @@ public:
/* 快速排序类(中位基准数优化) */ /* 快速排序类(中位基准数优化) */
class QuickSortMedian { class QuickSortMedian {
private: private:
/* 元素交换 */ /* 元素交换 */
static void swap(vector<int>& nums, int i, int j) { static void swap(vector<int> &nums, int i, int j) {
int tmp = nums[i]; int tmp = nums[i];
nums[i] = nums[j]; nums[i] = nums[j];
nums[j] = tmp; nums[j] = tmp;
} }
/* 选取三个元素的中位数 */ /* 选取三个元素的中位数 */
static int medianThree(vector<int>& nums, int left, int mid, int right) { static int medianThree(vector<int> &nums, int left, int mid, int right) {
// 此处使用异或运算来简化代码 // 此处使用异或运算来简化代码
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 // 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right]))
@ -68,7 +68,7 @@ private:
} }
/* 哨兵划分(三数取中值) */ /* 哨兵划分(三数取中值) */
static int partition(vector<int>& nums, int left, int right) { static int partition(vector<int> &nums, int left, int right) {
// 选取三个候选元素的中位数 // 选取三个候选元素的中位数
int med = medianThree(nums, left, (left + right) / 2, right); int med = medianThree(nums, left, (left + right) / 2, right);
// 将中位数交换至数组最左端 // 将中位数交换至数组最左端
@ -77,18 +77,18 @@ private:
int i = left, j = right; int i = left, j = right;
while (i < j) { while (i < j) {
while (i < j && nums[j] >= nums[left]) while (i < j && nums[j] >= nums[left])
j--; // 从右向左找首个小于基准数的元素 j--; // 从右向左找首个小于基准数的元素
while (i < j && nums[i] <= nums[left]) while (i < j && nums[i] <= nums[left])
i++; // 从左向右找首个大于基准数的元素 i++; // 从左向右找首个大于基准数的元素
swap(nums, i, j); // 交换这两个元素 swap(nums, i, j); // 交换这两个元素
} }
swap(nums, i, left); // 将基准数交换至两子数组的分界线 swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引 return i; // 返回基准数的索引
} }
public: public:
/* 快速排序 */ /* 快速排序 */
static void quickSort(vector<int>& nums, int left, int right) { static void quickSort(vector<int> &nums, int left, int right) {
// 子数组长度为 1 时终止递归 // 子数组长度为 1 时终止递归
if (left >= right) if (left >= right)
return; return;
@ -102,68 +102,67 @@ public:
/* 快速排序类(尾递归优化) */ /* 快速排序类(尾递归优化) */
class QuickSortTailCall { class QuickSortTailCall {
private: private:
/* 元素交换 */ /* 元素交换 */
static void swap(vector<int>& nums, int i, int j) { static void swap(vector<int> &nums, int i, int j) {
int tmp = nums[i]; int tmp = nums[i];
nums[i] = nums[j]; nums[i] = nums[j];
nums[j] = tmp; nums[j] = tmp;
} }
/* 哨兵划分 */ /* 哨兵划分 */
static int partition(vector<int>& nums, int left, int right) { static int partition(vector<int> &nums, int left, int right) {
// 以 nums[left] 作为基准数 // 以 nums[left] 作为基准数
int i = left, j = right; int i = left, j = right;
while (i < j) { while (i < j) {
while (i < j && nums[j] >= nums[left]) while (i < j && nums[j] >= nums[left])
j--; // 从右向左找首个小于基准数的元素 j--; // 从右向左找首个小于基准数的元素
while (i < j && nums[i] <= nums[left]) while (i < j && nums[i] <= nums[left])
i++; // 从左向右找首个大于基准数的元素 i++; // 从左向右找首个大于基准数的元素
swap(nums, i, j); // 交换这两个元素 swap(nums, i, j); // 交换这两个元素
} }
swap(nums, i, left); // 将基准数交换至两子数组的分界线 swap(nums, i, left); // 将基准数交换至两子数组的分界线
return i; // 返回基准数的索引 return i; // 返回基准数的索引
} }
public: public:
/* 快速排序(尾递归优化) */ /* 快速排序(尾递归优化) */
static void quickSort(vector<int>& nums, int left, int right) { static void quickSort(vector<int> &nums, int left, int right) {
// 子数组长度为 1 时终止 // 子数组长度为 1 时终止
while (left < right) { while (left < right) {
// 哨兵划分操作 // 哨兵划分操作
int pivot = partition(nums, left, right); int pivot = partition(nums, left, right);
// 对两个子数组中较短的那个执行快排 // 对两个子数组中较短的那个执行快排
if (pivot - left < right - pivot) { if (pivot - left < right - pivot) {
quickSort(nums, left, pivot - 1); // 递归排序左子数组 quickSort(nums, left, pivot - 1); // 递归排序左子数组
left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right] left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right]
} else { } else {
quickSort(nums, pivot + 1, right); // 递归排序右子数组 quickSort(nums, pivot + 1, right); // 递归排序右子数组
right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1] right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1]
} }
} }
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 快速排序 */ /* 快速排序 */
vector<int> nums { 2, 4, 1, 0, 3, 5 }; vector<int> nums{2, 4, 1, 0, 3, 5};
QuickSort::quickSort(nums, 0, nums.size() - 1); QuickSort::quickSort(nums, 0, nums.size() - 1);
cout << "快速排序完成后 nums = "; cout << "快速排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
/* 快速排序(中位基准数优化) */ /* 快速排序(中位基准数优化) */
vector<int> nums1 = { 2, 4, 1, 0, 3, 5 }; vector<int> nums1 = {2, 4, 1, 0, 3, 5};
QuickSortMedian::quickSort(nums1, 0, nums1.size() - 1); QuickSortMedian::quickSort(nums1, 0, nums1.size() - 1);
cout << "快速排序(中位基准数优化)完成后 nums = "; cout << "快速排序(中位基准数优化)完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
/* 快速排序(尾递归优化) */ /* 快速排序(尾递归优化) */
vector<int> nums2 = { 2, 4, 1, 0, 3, 5 }; vector<int> nums2 = {2, 4, 1, 0, 3, 5};
QuickSortTailCall::quickSort(nums2, 0, nums2.size() - 1); QuickSortTailCall::quickSort(nums2, 0, nums2.size() - 1);
cout << "快速排序(尾递归优化)完成后 nums = "; cout << "快速排序(尾递归优化)完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
return 0; return 0;
} }

View File

@ -14,7 +14,7 @@ int digit(int num, int exp) {
} }
/* 计数排序(根据 nums 第 k 位排序) */ /* 计数排序(根据 nums 第 k 位排序) */
void countingSortDigit(vector<int>& nums, int exp) { void countingSortDigit(vector<int> &nums, int exp) {
// 十进制的位范围为 0~9 ,因此需要长度为 10 的桶 // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶
vector<int> counter(10, 0); vector<int> counter(10, 0);
int n = nums.size(); int n = nums.size();
@ -41,7 +41,7 @@ void countingSortDigit(vector<int>& nums, int exp) {
} }
/* 基数排序 */ /* 基数排序 */
void radixSort(vector<int>& nums) { void radixSort(vector<int> &nums) {
// 获取数组的最大元素,用于判断最大位数 // 获取数组的最大元素,用于判断最大位数
int m = *max_element(nums.begin(), nums.end()); int m = *max_element(nums.begin(), nums.end());
// 按照从低位到高位的顺序遍历 // 按照从低位到高位的顺序遍历
@ -56,11 +56,11 @@ void radixSort(vector<int>& nums) {
/* Driver Code */ /* Driver Code */
int main() { int main() {
// 基数排序 // 基数排序
vector<int> nums = { 10546151, 35663510, 42865989, 34862445, 81883077, vector<int> nums = {10546151, 35663510, 42865989, 34862445, 81883077,
88906420, 72429244, 30524779, 82060337, 63832996 }; 88906420, 72429244, 30524779, 82060337, 63832996};
radixSort(nums); radixSort(nums);
cout << "基数排序完成后 nums = "; cout << "基数排序完成后 nums = ";
PrintUtil::printVector(nums); printVector(nums);
return 0; return 0;
} }

View File

@ -6,15 +6,14 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 基于环形数组实现的双向队列 */ /* 基于环形数组实现的双向队列 */
class ArrayDeque { class ArrayDeque {
private: private:
vector<int> nums; // 用于存储双向队列元素的数组 vector<int> nums; // 用于存储双向队列元素的数组
int front; // 队首指针,指向队首元素 int front; // 队首指针,指向队首元素
int queSize; // 双向队列长度 int queSize; // 双向队列长度
public: public:
/* 构造方法 */ /* 构造方法 */
ArrayDeque(int capacity) { ArrayDeque(int capacity) {
nums.resize(capacity); nums.resize(capacity);
@ -122,7 +121,7 @@ int main() {
deque->pushLast(2); deque->pushLast(2);
deque->pushLast(5); deque->pushLast(5);
cout << "双向队列 deque = "; cout << "双向队列 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 访问元素 */ /* 访问元素 */
int peekFirst = deque->peekFirst(); int peekFirst = deque->peekFirst();
@ -133,18 +132,18 @@ int main() {
/* 元素入队 */ /* 元素入队 */
deque->pushLast(4); deque->pushLast(4);
cout << "元素 4 队尾入队后 deque = "; cout << "元素 4 队尾入队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
deque->pushFirst(1); deque->pushFirst(1);
cout << "元素 1 队首入队后 deque = "; cout << "元素 1 队首入队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 元素出队 */ /* 元素出队 */
int popLast = deque->popLast(); int popLast = deque->popLast();
cout << "队尾出队元素 = " << popLast << ",队尾出队后 deque = "; cout << "队尾出队元素 = " << popLast << ",队尾出队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
int popFirst = deque->popFirst(); int popFirst = deque->popFirst();
cout << "队首出队元素 = " << popFirst << ",队首出队后 deque = "; cout << "队首出队元素 = " << popFirst << ",队首出队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 获取双向队列的长度 */ /* 获取双向队列的长度 */
int size = deque->size(); int size = deque->size();

View File

@ -8,13 +8,13 @@
/* 基于环形数组实现的队列 */ /* 基于环形数组实现的队列 */
class ArrayQueue { class ArrayQueue {
private: private:
int *nums; // 用于存储队列元素的数组 int *nums; // 用于存储队列元素的数组
int front; // 队首指针,指向队首元素 int front; // 队首指针,指向队首元素
int queSize; // 队列长度 int queSize; // 队列长度
int queCapacity; // 队列容量 int queCapacity; // 队列容量
public: public:
ArrayQueue(int capacity) { ArrayQueue(int capacity) {
// 初始化数组 // 初始化数组
nums = new int[capacity]; nums = new int[capacity];
@ -81,12 +81,11 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化队列 */ /* 初始化队列 */
int capacity = 10; int capacity = 10;
ArrayQueue* queue = new ArrayQueue(capacity); ArrayQueue *queue = new ArrayQueue(capacity);
/* 元素入队 */ /* 元素入队 */
queue->push(1); queue->push(1);
@ -95,16 +94,16 @@ int main() {
queue->push(5); queue->push(5);
queue->push(4); queue->push(4);
cout << "队列 queue = "; cout << "队列 queue = ";
PrintUtil::printVector(queue->toVector()); printVector(queue->toVector());
/* 访问队首元素 */ /* 访问队首元素 */
int peek = queue->peek(); int peek = queue->peek();
cout << "队首元素 peek = " << peek << endl; cout << "队首元素 peek = " << peek << endl;
/* 元素出队 */ /* 元素出队 */
queue->pop(); queue->pop();
cout << "出队元素 pop = " << peek << ",出队后 queue = "; cout << "出队元素 pop = " << peek << ",出队后 queue = ";
PrintUtil::printVector(queue->toVector()); printVector(queue->toVector());
/* 获取队列的长度 */ /* 获取队列的长度 */
int size = queue->size(); int size = queue->size();
@ -119,7 +118,7 @@ int main() {
queue->push(i); queue->push(i);
queue->pop(); queue->pop();
cout << "" << i << " 轮入队 + 出队后 queue = "; cout << "" << i << " 轮入队 + 出队后 queue = ";
PrintUtil::printVector(queue->toVector()); printVector(queue->toVector());
} }
// 释放内存 // 释放内存

View File

@ -8,10 +8,10 @@
/* 基于数组实现的栈 */ /* 基于数组实现的栈 */
class ArrayStack { class ArrayStack {
private: private:
vector<int> stack; vector<int> stack;
public: public:
/* 获取栈的长度 */ /* 获取栈的长度 */
int size() { int size() {
return stack.size(); return stack.size();
@ -35,7 +35,7 @@ public:
/* 访问栈顶元素 */ /* 访问栈顶元素 */
int top() { int top() {
if(empty()) if (empty())
throw out_of_range("栈为空"); throw out_of_range("栈为空");
return stack.back(); return stack.back();
} }
@ -46,11 +46,10 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化栈 */ /* 初始化栈 */
ArrayStack* stack = new ArrayStack(); ArrayStack *stack = new ArrayStack();
/* 元素入栈 */ /* 元素入栈 */
stack->push(1); stack->push(1);
@ -59,7 +58,7 @@ int main() {
stack->push(5); stack->push(5);
stack->push(4); stack->push(4);
cout << "栈 stack = "; cout << "栈 stack = ";
PrintUtil::printVector(stack->toVector()); printVector(stack->toVector());
/* 访问栈顶元素 */ /* 访问栈顶元素 */
int top = stack->top(); int top = stack->top();
@ -68,7 +67,7 @@ int main() {
/* 元素出栈 */ /* 元素出栈 */
stack->pop(); stack->pop();
cout << "出栈元素 pop = " << top << ",出栈后 stack = "; cout << "出栈元素 pop = " << top << ",出栈后 stack = ";
PrintUtil::printVector(stack->toVector()); printVector(stack->toVector());
/* 获取栈的长度 */ /* 获取栈的长度 */
int size = stack->size(); int size = stack->size();

View File

@ -6,7 +6,6 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化双向队列 */ /* 初始化双向队列 */
@ -19,7 +18,7 @@ int main() {
deque.push_front(3); deque.push_front(3);
deque.push_front(1); deque.push_front(1);
cout << "双向队列 deque = "; cout << "双向队列 deque = ";
PrintUtil::printDeque(deque); printDeque(deque);
/* 访问元素 */ /* 访问元素 */
int front = deque.front(); int front = deque.front();
@ -30,10 +29,10 @@ int main() {
/* 元素出队 */ /* 元素出队 */
deque.pop_front(); deque.pop_front();
cout << "队首出队元素 popFront = " << front << ",队首出队后 deque = "; cout << "队首出队元素 popFront = " << front << ",队首出队后 deque = ";
PrintUtil::printDeque(deque); printDeque(deque);
deque.pop_back(); deque.pop_back();
cout << "队尾出队元素 popLast = " << back << ",队尾出队后 deque = "; cout << "队尾出队元素 popLast = " << back << ",队尾出队后 deque = ";
PrintUtil::printDeque(deque); printDeque(deque);
/* 获取双向队列的长度 */ /* 获取双向队列的长度 */
int size = deque.size(); int size = deque.size();

View File

@ -6,24 +6,25 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 双向链表节点 */ /* 双向链表节点 */
struct DoublyListNode { struct DoublyListNode {
int val; // 节点值 int val; // 节点值
DoublyListNode *next; // 后继节点指针 DoublyListNode *next; // 后继节点指针
DoublyListNode *prev; // 前驱节点指针 DoublyListNode *prev; // 前驱节点指针
DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {} DoublyListNode(int val) : val(val), prev(nullptr), next(nullptr) {
}
}; };
/* 基于双向链表实现的双向队列 */ /* 基于双向链表实现的双向队列 */
class LinkedListDeque { class LinkedListDeque {
private: private:
DoublyListNode *front, *rear; // 头节点 front ,尾节点 rear DoublyListNode *front, *rear; // 头节点 front ,尾节点 rear
int queSize = 0; // 双向队列的长度 int queSize = 0; // 双向队列的长度
public: public:
/* 构造方法 */ /* 构造方法 */
LinkedListDeque() : front(nullptr), rear(nullptr) {} LinkedListDeque() : front(nullptr), rear(nullptr) {
}
/* 析构方法 */ /* 析构方法 */
~LinkedListDeque() { ~LinkedListDeque() {
@ -63,7 +64,7 @@ public:
// 将 node 添加至链表尾部 // 将 node 添加至链表尾部
rear->next = node; rear->next = node;
node->prev = rear; node->prev = rear;
rear = node; // 更新尾节点 rear = node; // 更新尾节点
} }
queSize++; // 更新队列长度 queSize++; // 更新队列长度
} }
@ -94,7 +95,7 @@ public:
front->next = nullptr; front->next = nullptr;
delete front; delete front;
} }
front = fNext; // 更新头节点 front = fNext; // 更新头节点
// 队尾出队操作 // 队尾出队操作
} else { } else {
val = rear->val; // 暂存尾节点值 val = rear->val; // 暂存尾节点值
@ -105,7 +106,7 @@ public:
rear->prev = nullptr; rear->prev = nullptr;
delete rear; delete rear;
} }
rear = rPrev; // 更新尾节点 rear = rPrev; // 更新尾节点
} }
queSize--; // 更新队列长度 queSize--; // 更新队列长度
return val; return val;
@ -151,7 +152,7 @@ int main() {
deque->pushLast(2); deque->pushLast(2);
deque->pushLast(5); deque->pushLast(5);
cout << "双向队列 deque = "; cout << "双向队列 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 访问元素 */ /* 访问元素 */
int peekFirst = deque->peekFirst(); int peekFirst = deque->peekFirst();
@ -161,19 +162,19 @@ int main() {
/* 元素入队 */ /* 元素入队 */
deque->pushLast(4); deque->pushLast(4);
cout << "元素 4 队尾入队后 deque =" ; cout << "元素 4 队尾入队后 deque =";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
deque->pushFirst(1); deque->pushFirst(1);
cout << "元素 1 队首入队后 deque = "; cout << "元素 1 队首入队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 元素出队 */ /* 元素出队 */
int popLast = deque->popLast(); int popLast = deque->popLast();
cout << "队尾出队元素 = " << popLast << ",队尾出队后 deque = "; cout << "队尾出队元素 = " << popLast << ",队尾出队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
int popFirst = deque->popFirst(); int popFirst = deque->popFirst();
cout << "队首出队元素 = " << popFirst << ",队首出队后 deque = "; cout << "队首出队元素 = " << popFirst << ",队首出队后 deque = ";
PrintUtil::printVector(deque->toVector()); printVector(deque->toVector());
/* 获取双向队列的长度 */ /* 获取双向队列的长度 */
int size = deque->size(); int size = deque->size();

View File

@ -8,11 +8,11 @@
/* 基于链表实现的队列 */ /* 基于链表实现的队列 */
class LinkedListQueue { class LinkedListQueue {
private: private:
ListNode *front, *rear; // 头节点 front ,尾节点 rear ListNode *front, *rear; // 头节点 front ,尾节点 rear
int queSize; int queSize;
public: public:
LinkedListQueue() { LinkedListQueue() {
front = nullptr; front = nullptr;
rear = nullptr; rear = nullptr;
@ -37,7 +37,7 @@ public:
/* 入队 */ /* 入队 */
void push(int num) { void push(int num) {
// 尾节点后添加 num // 尾节点后添加 num
ListNode* node = new ListNode(num); ListNode *node = new ListNode(num);
// 如果队列为空,则令头、尾节点都指向该节点 // 如果队列为空,则令头、尾节点都指向该节点
if (front == nullptr) { if (front == nullptr) {
front = node; front = node;
@ -58,7 +58,7 @@ public:
ListNode *tmp = front; ListNode *tmp = front;
front = front->next; front = front->next;
// 释放内存 // 释放内存
delete tmp; delete tmp;
queSize--; queSize--;
} }
@ -71,7 +71,7 @@ public:
/* 将链表转化为 Vector 并返回 */ /* 将链表转化为 Vector 并返回 */
vector<int> toVector() { vector<int> toVector() {
ListNode* node = front; ListNode *node = front;
vector<int> res(size()); vector<int> res(size());
for (int i = 0; i < res.size(); i++) { for (int i = 0; i < res.size(); i++) {
res[i] = node->val; res[i] = node->val;
@ -81,11 +81,10 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化队列 */ /* 初始化队列 */
LinkedListQueue* queue = new LinkedListQueue(); LinkedListQueue *queue = new LinkedListQueue();
/* 元素入队 */ /* 元素入队 */
queue->push(1); queue->push(1);
@ -94,7 +93,7 @@ int main() {
queue->push(5); queue->push(5);
queue->push(4); queue->push(4);
cout << "队列 queue = "; cout << "队列 queue = ";
PrintUtil::printVector(queue->toVector()); printVector(queue->toVector());
/* 访问队首元素 */ /* 访问队首元素 */
int peek = queue->peek(); int peek = queue->peek();
@ -103,7 +102,7 @@ int main() {
/* 元素出队 */ /* 元素出队 */
queue->pop(); queue->pop();
cout << "出队元素 pop = " << peek << ",出队后 queue = "; cout << "出队元素 pop = " << peek << ",出队后 queue = ";
PrintUtil::printVector(queue->toVector()); printVector(queue->toVector());
/* 获取队列的长度 */ /* 获取队列的长度 */
int size = queue->size(); int size = queue->size();

View File

@ -8,11 +8,11 @@
/* 基于链表实现的栈 */ /* 基于链表实现的栈 */
class LinkedListStack { class LinkedListStack {
private: private:
ListNode* stackTop; // 将头节点作为栈顶 ListNode *stackTop; // 将头节点作为栈顶
int stkSize; // 栈的长度 int stkSize; // 栈的长度
public: public:
LinkedListStack() { LinkedListStack() {
stackTop = nullptr; stackTop = nullptr;
stkSize = 0; stkSize = 0;
@ -35,7 +35,7 @@ public:
/* 入栈 */ /* 入栈 */
void push(int num) { void push(int num) {
ListNode* node = new ListNode(num); ListNode *node = new ListNode(num);
node->next = stackTop; node->next = stackTop;
stackTop = node; stackTop = node;
stkSize++; stkSize++;
@ -60,7 +60,7 @@ public:
/* 将 List 转化为 Array 并返回 */ /* 将 List 转化为 Array 并返回 */
vector<int> toVector() { vector<int> toVector() {
ListNode* node = stackTop; ListNode *node = stackTop;
vector<int> res(size()); vector<int> res(size());
for (int i = res.size() - 1; i >= 0; i--) { for (int i = res.size() - 1; i >= 0; i--) {
res[i] = node->val; res[i] = node->val;
@ -70,11 +70,10 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化栈 */ /* 初始化栈 */
LinkedListStack* stack = new LinkedListStack(); LinkedListStack *stack = new LinkedListStack();
/* 元素入栈 */ /* 元素入栈 */
stack->push(1); stack->push(1);
@ -83,7 +82,7 @@ int main() {
stack->push(5); stack->push(5);
stack->push(4); stack->push(4);
cout << "栈 stack = "; cout << "栈 stack = ";
PrintUtil::printVector(stack->toVector()); printVector(stack->toVector());
/* 访问栈顶元素 */ /* 访问栈顶元素 */
int top = stack->top(); int top = stack->top();
@ -92,7 +91,7 @@ int main() {
/* 元素出栈 */ /* 元素出栈 */
stack->pop(); stack->pop();
cout << "出栈元素 pop = " << top << ",出栈后 stack = "; cout << "出栈元素 pop = " << top << ",出栈后 stack = ";
PrintUtil::printVector(stack->toVector()); printVector(stack->toVector());
/* 获取栈的长度 */ /* 获取栈的长度 */
int size = stack->size(); int size = stack->size();

View File

@ -6,12 +6,11 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main(){ int main() {
/* 初始化队列 */ /* 初始化队列 */
queue<int> queue; queue<int> queue;
/* 元素入队 */ /* 元素入队 */
queue.push(1); queue.push(1);
queue.push(3); queue.push(3);
@ -19,24 +18,24 @@ int main(){
queue.push(5); queue.push(5);
queue.push(4); queue.push(4);
cout << "队列 queue = "; cout << "队列 queue = ";
PrintUtil::printQueue(queue); printQueue(queue);
/* 访问队首元素 */ /* 访问队首元素 */
int front = queue.front(); int front = queue.front();
cout << "队首元素 front = " << front << endl; cout << "队首元素 front = " << front << endl;
/* 元素出队 */ /* 元素出队 */
queue.pop(); queue.pop();
cout << "出队元素 front = " << front << ",出队后 queue = "; cout << "出队元素 front = " << front << ",出队后 queue = ";
PrintUtil::printQueue(queue); printQueue(queue);
/* 获取队列的长度 */ /* 获取队列的长度 */
int size = queue.size(); int size = queue.size();
cout << "队列长度 size = " << size << endl; cout << "队列长度 size = " << size << endl;
/* 判断队列是否为空 */ /* 判断队列是否为空 */
bool empty = queue.empty(); bool empty = queue.empty();
cout << "队列是否为空 = " << empty << endl; cout << "队列是否为空 = " << empty << endl;
return 0; return 0;
} }

View File

@ -6,7 +6,6 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化栈 */ /* 初始化栈 */
@ -19,7 +18,7 @@ int main() {
stack.push(5); stack.push(5);
stack.push(4); stack.push(4);
cout << "栈 stack = "; cout << "栈 stack = ";
PrintUtil::printStack(stack); printStack(stack);
/* 访问栈顶元素 */ /* 访问栈顶元素 */
int top = stack.top(); int top = stack.top();
@ -28,7 +27,7 @@ int main() {
/* 元素出栈 */ /* 元素出栈 */
stack.pop(); // 无返回值 stack.pop(); // 无返回值
cout << "出栈元素 pop = " << top << ",出栈后 stack = "; cout << "出栈元素 pop = " << top << ",出栈后 stack = ";
PrintUtil::printStack(stack); printStack(stack);
/* 获取栈的长度 */ /* 获取栈的长度 */
int size = stack.size(); int size = stack.size();

View File

@ -8,19 +8,19 @@
/* AVL 树 */ /* AVL 树 */
class AVLTree { class AVLTree {
public: public:
TreeNode* root; // 根节点 TreeNode *root; // 根节点
private: private:
/* 更新节点高度 */ /* 更新节点高度 */
void updateHeight(TreeNode* node) { void updateHeight(TreeNode *node) {
// 节点高度等于最高子树高度 + 1 // 节点高度等于最高子树高度 + 1
node->height = max(height(node->left), height(node->right)) + 1; node->height = max(height(node->left), height(node->right)) + 1;
} }
/* 右旋操作 */ /* 右旋操作 */
TreeNode* rightRotate(TreeNode* node) { TreeNode *rightRotate(TreeNode *node) {
TreeNode* child = node->left; TreeNode *child = node->left;
TreeNode* grandChild = child->right; TreeNode *grandChild = child->right;
// 以 child 为原点,将 node 向右旋转 // 以 child 为原点,将 node 向右旋转
child->right = node; child->right = node;
node->left = grandChild; node->left = grandChild;
@ -32,9 +32,9 @@ private:
} }
/* 左旋操作 */ /* 左旋操作 */
TreeNode* leftRotate(TreeNode* node) { TreeNode *leftRotate(TreeNode *node) {
TreeNode* child = node->right; TreeNode *child = node->right;
TreeNode* grandChild = child->left; TreeNode *grandChild = child->left;
// 以 child 为原点,将 node 向左旋转 // 以 child 为原点,将 node 向左旋转
child->left = node; child->left = node;
node->right = grandChild; node->right = grandChild;
@ -46,7 +46,7 @@ private:
} }
/* 执行旋转操作,使该子树重新恢复平衡 */ /* 执行旋转操作,使该子树重新恢复平衡 */
TreeNode* rotate(TreeNode* node) { TreeNode *rotate(TreeNode *node) {
// 获取节点 node 的平衡因子 // 获取节点 node 的平衡因子
int _balanceFactor = balanceFactor(node); int _balanceFactor = balanceFactor(node);
// 左偏树 // 左偏树
@ -76,7 +76,7 @@ private:
} }
/* 递归插入节点(辅助方法) */ /* 递归插入节点(辅助方法) */
TreeNode* insertHelper(TreeNode* node, int val) { TreeNode *insertHelper(TreeNode *node, int val) {
if (node == nullptr) if (node == nullptr)
return new TreeNode(val); return new TreeNode(val);
/* 1. 查找插入位置,并插入节点 */ /* 1. 查找插入位置,并插入节点 */
@ -85,8 +85,8 @@ private:
else if (val > node->val) else if (val > node->val)
node->right = insertHelper(node->right, val); node->right = insertHelper(node->right, val);
else else
return node; // 重复节点不插入,直接返回 return node; // 重复节点不插入,直接返回
updateHeight(node); // 更新节点高度 updateHeight(node); // 更新节点高度
/* 2. 执行旋转操作,使该子树重新恢复平衡 */ /* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node); node = rotate(node);
// 返回子树的根节点 // 返回子树的根节点
@ -94,7 +94,7 @@ private:
} }
/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */
TreeNode* getInOrderNext(TreeNode* node) { TreeNode *getInOrderNext(TreeNode *node) {
if (node == nullptr) if (node == nullptr)
return node; return node;
// 循环访问左子节点,直到叶节点时为最小节点,跳出 // 循环访问左子节点,直到叶节点时为最小节点,跳出
@ -105,7 +105,7 @@ private:
} }
/* 递归删除节点(辅助方法) */ /* 递归删除节点(辅助方法) */
TreeNode* removeHelper(TreeNode* node, int val) { TreeNode *removeHelper(TreeNode *node, int val) {
if (node == nullptr) if (node == nullptr)
return nullptr; return nullptr;
/* 1. 查找节点,并删除之 */ /* 1. 查找节点,并删除之 */
@ -115,7 +115,7 @@ private:
node->right = removeHelper(node->right, val); node->right = removeHelper(node->right, val);
else { else {
if (node->left == nullptr || node->right == nullptr) { if (node->left == nullptr || node->right == nullptr) {
TreeNode* child = node->left != nullptr ? node->left : node->right; TreeNode *child = node->left != nullptr ? node->left : node->right;
// 子节点数量 = 0 ,直接删除 node 并返回 // 子节点数量 = 0 ,直接删除 node 并返回
if (child == nullptr) { if (child == nullptr) {
delete node; delete node;
@ -128,49 +128,50 @@ private:
} }
} else { } else {
// 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点
TreeNode* temp = getInOrderNext(node->right); TreeNode *temp = getInOrderNext(node->right);
int tempVal = temp->val; int tempVal = temp->val;
node->right = removeHelper(node->right, temp->val); node->right = removeHelper(node->right, temp->val);
node->val = tempVal; node->val = tempVal;
} }
} }
updateHeight(node); // 更新节点高度 updateHeight(node); // 更新节点高度
/* 2. 执行旋转操作,使该子树重新恢复平衡 */ /* 2. 执行旋转操作,使该子树重新恢复平衡 */
node = rotate(node); node = rotate(node);
// 返回子树的根节点 // 返回子树的根节点
return node; return node;
} }
public: public:
/* 获取节点高度 */ /* 获取节点高度 */
int height(TreeNode* node) { int height(TreeNode *node) {
// 空节点高度为 -1 ,叶节点高度为 0 // 空节点高度为 -1 ,叶节点高度为 0
return node == nullptr ? -1 : node->height; return node == nullptr ? -1 : node->height;
} }
/* 获取平衡因子 */ /* 获取平衡因子 */
int balanceFactor(TreeNode* node) { int balanceFactor(TreeNode *node) {
// 空节点平衡因子为 0 // 空节点平衡因子为 0
if (node == nullptr) return 0; if (node == nullptr)
return 0;
// 节点平衡因子 = 左子树高度 - 右子树高度 // 节点平衡因子 = 左子树高度 - 右子树高度
return height(node->left) - height(node->right); return height(node->left) - height(node->right);
} }
/* 插入节点 */ /* 插入节点 */
TreeNode* insert(int val) { TreeNode *insert(int val) {
root = insertHelper(root, val); root = insertHelper(root, val);
return root; return root;
} }
/* 删除节点 */ /* 删除节点 */
TreeNode* remove(int val) { TreeNode *remove(int val) {
root = removeHelper(root, val); root = removeHelper(root, val);
return root; return root;
} }
/* 查找节点 */ /* 查找节点 */
TreeNode* search(int val) { TreeNode *search(int val) {
TreeNode* cur = root; TreeNode *cur = root;
// 循环查找,越过叶节点后跳出 // 循环查找,越过叶节点后跳出
while (cur != nullptr) { while (cur != nullptr) {
// 目标节点在 cur 的右子树中 // 目标节点在 cur 的右子树中
@ -188,7 +189,8 @@ public:
} }
/*构造方法*/ /*构造方法*/
AVLTree() : root(nullptr) {} AVLTree() : root(nullptr) {
}
/*析构方法*/ /*析构方法*/
~AVLTree() { ~AVLTree() {
@ -196,16 +198,16 @@ public:
} }
}; };
void testInsert(AVLTree& tree, int val) { void testInsert(AVLTree &tree, int val) {
tree.insert(val); tree.insert(val);
cout << "\n插入节点 " << val << "AVL 树为" << endl; cout << "\n插入节点 " << val << "AVL 树为" << endl;
PrintUtil::printTree(tree.root); printTree(tree.root);
} }
void testRemove(AVLTree& tree, int val) { void testRemove(AVLTree &tree, int val) {
tree.remove(val); tree.remove(val);
cout << "\n删除节点 " << val << "AVL 树为" << endl; cout << "\n删除节点 " << val << "AVL 树为" << endl;
PrintUtil::printTree(tree.root); printTree(tree.root);
} }
int main() { int main() {
/* 初始化空 AVL 树 */ /* 初始化空 AVL 树 */
@ -229,11 +231,11 @@ int main() {
/* 删除节点 */ /* 删除节点 */
// 请关注删除节点后AVL 树是如何保持平衡的 // 请关注删除节点后AVL 树是如何保持平衡的
testRemove(avlTree, 8); // 删除度为 0 的节点 testRemove(avlTree, 8); // 删除度为 0 的节点
testRemove(avlTree, 5); // 删除度为 1 的节点 testRemove(avlTree, 5); // 删除度为 1 的节点
testRemove(avlTree, 4); // 删除度为 2 的节点 testRemove(avlTree, 4); // 删除度为 2 的节点
/* 查询节点 */ /* 查询节点 */
TreeNode* node = avlTree.search(7); TreeNode *node = avlTree.search(7);
cout << "\n查找到的节点对象为 " << node << ",节点值 = " << node->val << endl; cout << "\n查找到的节点对象为 " << node << ",节点值 = " << node->val << endl;
} }

View File

@ -8,13 +8,13 @@
/* 二叉搜索树 */ /* 二叉搜索树 */
class BinarySearchTree { class BinarySearchTree {
private: private:
TreeNode* root; TreeNode *root;
public: public:
BinarySearchTree(vector<int> nums) { BinarySearchTree(vector<int> nums) {
sort(nums.begin(), nums.end()); // 排序数组 sort(nums.begin(), nums.end()); // 排序数组
root = buildTree(nums, 0, nums.size() - 1); // 构建二叉搜索树 root = buildTree(nums, 0, nums.size() - 1); // 构建二叉搜索树
} }
~BinarySearchTree() { ~BinarySearchTree() {
@ -22,16 +22,17 @@ public:
} }
/* 获取二叉树根节点 */ /* 获取二叉树根节点 */
TreeNode* getRoot() { TreeNode *getRoot() {
return root; return root;
} }
/* 构建二叉搜索树 */ /* 构建二叉搜索树 */
TreeNode* buildTree(vector<int> nums, int i, int j) { TreeNode *buildTree(vector<int> nums, int i, int j) {
if (i > j) return nullptr; if (i > j)
return nullptr;
// 将数组中间节点作为根节点 // 将数组中间节点作为根节点
int mid = (i + j) / 2; int mid = (i + j) / 2;
TreeNode* root = new TreeNode(nums[mid]); TreeNode *root = new TreeNode(nums[mid]);
// 递归建立左子树和右子树 // 递归建立左子树和右子树
root->left = buildTree(nums, i, mid - 1); root->left = buildTree(nums, i, mid - 1);
root->right = buildTree(nums, mid + 1, j); root->right = buildTree(nums, mid + 1, j);
@ -39,74 +40,90 @@ public:
} }
/* 查找节点 */ /* 查找节点 */
TreeNode* search(int num) { TreeNode *search(int num) {
TreeNode* cur = root; TreeNode *cur = root;
// 循环查找,越过叶节点后跳出 // 循环查找,越过叶节点后跳出
while (cur != nullptr) { while (cur != nullptr) {
// 目标节点在 cur 的右子树中 // 目标节点在 cur 的右子树中
if (cur->val < num) cur = cur->right; if (cur->val < num)
cur = cur->right;
// 目标节点在 cur 的左子树中 // 目标节点在 cur 的左子树中
else if (cur->val > num) cur = cur->left; else if (cur->val > num)
cur = cur->left;
// 找到目标节点,跳出循环 // 找到目标节点,跳出循环
else break; else
break;
} }
// 返回目标节点 // 返回目标节点
return cur; return cur;
} }
/* 插入节点 */ /* 插入节点 */
TreeNode* insert(int num) { TreeNode *insert(int num) {
// 若树为空,直接提前返回 // 若树为空,直接提前返回
if (root == nullptr) return nullptr; if (root == nullptr)
return nullptr;
TreeNode *cur = root, *pre = nullptr; TreeNode *cur = root, *pre = nullptr;
// 循环查找,越过叶节点后跳出 // 循环查找,越过叶节点后跳出
while (cur != nullptr) { while (cur != nullptr) {
// 找到重复节点,直接返回 // 找到重复节点,直接返回
if (cur->val == num) return nullptr; if (cur->val == num)
return nullptr;
pre = cur; pre = cur;
// 插入位置在 cur 的右子树中 // 插入位置在 cur 的右子树中
if (cur->val < num) cur = cur->right; if (cur->val < num)
cur = cur->right;
// 插入位置在 cur 的左子树中 // 插入位置在 cur 的左子树中
else cur = cur->left; else
cur = cur->left;
} }
// 插入节点 val // 插入节点 val
TreeNode* node = new TreeNode(num); TreeNode *node = new TreeNode(num);
if (pre->val < num) pre->right = node; if (pre->val < num)
else pre->left = node; pre->right = node;
else
pre->left = node;
return node; return node;
} }
/* 删除节点 */ /* 删除节点 */
TreeNode* remove(int num) { TreeNode *remove(int num) {
// 若树为空,直接提前返回 // 若树为空,直接提前返回
if (root == nullptr) return nullptr; if (root == nullptr)
return nullptr;
TreeNode *cur = root, *pre = nullptr; TreeNode *cur = root, *pre = nullptr;
// 循环查找,越过叶节点后跳出 // 循环查找,越过叶节点后跳出
while (cur != nullptr) { while (cur != nullptr) {
// 找到待删除节点,跳出循环 // 找到待删除节点,跳出循环
if (cur->val == num) break; if (cur->val == num)
break;
pre = cur; pre = cur;
// 待删除节点在 cur 的右子树中 // 待删除节点在 cur 的右子树中
if (cur->val < num) cur = cur->right; if (cur->val < num)
cur = cur->right;
// 待删除节点在 cur 的左子树中 // 待删除节点在 cur 的左子树中
else cur = cur->left; else
cur = cur->left;
} }
// 若无待删除节点,则直接返回 // 若无待删除节点,则直接返回
if (cur == nullptr) return nullptr; if (cur == nullptr)
return nullptr;
// 子节点数量 = 0 or 1 // 子节点数量 = 0 or 1
if (cur->left == nullptr || cur->right == nullptr) { if (cur->left == nullptr || cur->right == nullptr) {
// 当子节点数量 = 0 / 1 时, child = nullptr / 该子节点 // 当子节点数量 = 0 / 1 时, child = nullptr / 该子节点
TreeNode* child = cur->left != nullptr ? cur->left : cur->right; TreeNode *child = cur->left != nullptr ? cur->left : cur->right;
// 删除节点 cur // 删除节点 cur
if (pre->left == cur) pre->left = child; if (pre->left == cur)
else pre->right = child; pre->left = child;
else
pre->right = child;
// 释放内存 // 释放内存
delete cur; delete cur;
} }
// 子节点数量 = 2 // 子节点数量 = 2
else { else {
// 获取中序遍历中 cur 的下一个节点 // 获取中序遍历中 cur 的下一个节点
TreeNode* nex = getInOrderNext(cur->right); TreeNode *nex = getInOrderNext(cur->right);
int tmp = nex->val; int tmp = nex->val;
// 递归删除节点 nex // 递归删除节点 nex
remove(nex->val); remove(nex->val);
@ -117,8 +134,9 @@ public:
} }
/* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */ /* 获取中序遍历中的下一个节点(仅适用于 root 有左子节点的情况) */
TreeNode* getInOrderNext(TreeNode* root) { TreeNode *getInOrderNext(TreeNode *root) {
if (root == nullptr) return root; if (root == nullptr)
return root;
// 循环访问左子节点,直到叶节点时为最小节点,跳出 // 循环访问左子节点,直到叶节点时为最小节点,跳出
while (root->left != nullptr) { while (root->left != nullptr) {
root = root->left; root = root->left;
@ -127,34 +145,33 @@ public:
} }
}; };
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化二叉搜索树 */ /* 初始化二叉搜索树 */
vector<int> nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
BinarySearchTree* bst = new BinarySearchTree(nums); BinarySearchTree *bst = new BinarySearchTree(nums);
cout << endl << "初始化的二叉树为\n" << endl; cout << endl << "初始化的二叉树为\n" << endl;
PrintUtil::printTree(bst->getRoot()); printTree(bst->getRoot());
/* 查找节点 */ /* 查找节点 */
TreeNode* node = bst->search(7); TreeNode *node = bst->search(7);
cout << endl << "查找到的节点对象为 " << node << ",节点值 = " << node->val << endl; cout << endl << "查找到的节点对象为 " << node << ",节点值 = " << node->val << endl;
/* 插入节点 */ /* 插入节点 */
node = bst->insert(16); node = bst->insert(16);
cout << endl << "插入节点 16 后,二叉树为\n" << endl; cout << endl << "插入节点 16 后,二叉树为\n" << endl;
PrintUtil::printTree(bst->getRoot()); printTree(bst->getRoot());
/* 删除节点 */ /* 删除节点 */
bst->remove(1); bst->remove(1);
cout << endl << "删除节点 1 后,二叉树为\n" << endl; cout << endl << "删除节点 1 后,二叉树为\n" << endl;
PrintUtil::printTree(bst->getRoot()); printTree(bst->getRoot());
bst->remove(2); bst->remove(2);
cout << endl << "删除节点 2 后,二叉树为\n" << endl; cout << endl << "删除节点 2 后,二叉树为\n" << endl;
PrintUtil::printTree(bst->getRoot()); printTree(bst->getRoot());
bst->remove(4); bst->remove(4);
cout << endl << "删除节点 4 后,二叉树为\n" << endl; cout << endl << "删除节点 4 后,二叉树为\n" << endl;
PrintUtil::printTree(bst->getRoot()); printTree(bst->getRoot());
// 释放内存 // 释放内存
delete bst; delete bst;

View File

@ -6,36 +6,35 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化二叉树 */ /* 初始化二叉树 */
// 初始化节点 // 初始化节点
TreeNode* n1 = new TreeNode(1); TreeNode *n1 = new TreeNode(1);
TreeNode* n2 = new TreeNode(2); TreeNode *n2 = new TreeNode(2);
TreeNode* n3 = new TreeNode(3); TreeNode *n3 = new TreeNode(3);
TreeNode* n4 = new TreeNode(4); TreeNode *n4 = new TreeNode(4);
TreeNode* n5 = new TreeNode(5); TreeNode *n5 = new TreeNode(5);
// 构建引用指向(即指针) // 构建引用指向(即指针)
n1->left = n2; n1->left = n2;
n1->right = n3; n1->right = n3;
n2->left = n4; n2->left = n4;
n2->right = n5; n2->right = n5;
cout << endl << "初始化二叉树\n" << endl; cout << endl << "初始化二叉树\n" << endl;
PrintUtil::printTree(n1); printTree(n1);
/* 插入与删除节点 */ /* 插入与删除节点 */
TreeNode* P = new TreeNode(0); TreeNode *P = new TreeNode(0);
// 在 n1 -> n2 中间插入节点 P // 在 n1 -> n2 中间插入节点 P
n1->left = P; n1->left = P;
P->left = n2; P->left = n2;
cout << endl << "插入节点 P 后\n" << endl; cout << endl << "插入节点 P 后\n" << endl;
PrintUtil::printTree(n1); printTree(n1);
// 删除节点 P // 删除节点 P
n1->left = n2; n1->left = n2;
delete P; // 释放内存 delete P; // 释放内存
cout << endl << "删除节点 P 后\n" << endl; cout << endl << "删除节点 P 后\n" << endl;
PrintUtil::printTree(n1); printTree(n1);
// 释放内存 // 释放内存
freeMemoryTree(n1); freeMemoryTree(n1);

View File

@ -7,37 +7,36 @@
#include "../include/include.hpp" #include "../include/include.hpp"
/* 层序遍历 */ /* 层序遍历 */
vector<int> levelOrder(TreeNode* root) { vector<int> levelOrder(TreeNode *root) {
// 初始化队列,加入根节点 // 初始化队列,加入根节点
queue<TreeNode*> queue; queue<TreeNode *> queue;
queue.push(root); queue.push(root);
// 初始化一个列表,用于保存遍历序列 // 初始化一个列表,用于保存遍历序列
vector<int> vec; vector<int> vec;
while (!queue.empty()) { while (!queue.empty()) {
TreeNode* node = queue.front(); TreeNode *node = queue.front();
queue.pop(); // 队列出队 queue.pop(); // 队列出队
vec.push_back(node->val); // 保存节点值 vec.push_back(node->val); // 保存节点值
if (node->left != nullptr) if (node->left != nullptr)
queue.push(node->left); // 左子节点入队 queue.push(node->left); // 左子节点入队
if (node->right != nullptr) if (node->right != nullptr)
queue.push(node->right); // 右子节点入队 queue.push(node->right); // 右子节点入队
} }
return vec; return vec;
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化二叉树 */ /* 初始化二叉树 */
// 这里借助了一个从数组直接生成二叉树的函数 // 这里借助了一个从数组直接生成二叉树的函数
TreeNode* root = vecToTree(vector<int> { 1, 2, 3, 4, 5, 6, 7 }); TreeNode *root = vecToTree(vector<int>{1, 2, 3, 4, 5, 6, 7});
cout << endl << "初始化二叉树\n" << endl; cout << endl << "初始化二叉树\n" << endl;
PrintUtil::printTree(root); printTree(root);
/* 层序遍历 */ /* 层序遍历 */
vector<int> vec = levelOrder(root); vector<int> vec = levelOrder(root);
cout << endl << "层序遍历的节点打印序列 = "; cout << endl << "层序遍历的节点打印序列 = ";
PrintUtil::printVector(vec); printVector(vec);
return 0; return 0;
} }

View File

@ -10,8 +10,9 @@
vector<int> vec; vector<int> vec;
/* 前序遍历 */ /* 前序遍历 */
void preOrder(TreeNode* root) { void preOrder(TreeNode *root) {
if (root == nullptr) return; if (root == nullptr)
return;
// 访问优先级:根节点 -> 左子树 -> 右子树 // 访问优先级:根节点 -> 左子树 -> 右子树
vec.push_back(root->val); vec.push_back(root->val);
preOrder(root->left); preOrder(root->left);
@ -19,8 +20,9 @@ void preOrder(TreeNode* root) {
} }
/* 中序遍历 */ /* 中序遍历 */
void inOrder(TreeNode* root) { void inOrder(TreeNode *root) {
if (root == nullptr) return; if (root == nullptr)
return;
// 访问优先级:左子树 -> 根节点 -> 右子树 // 访问优先级:左子树 -> 根节点 -> 右子树
inOrder(root->left); inOrder(root->left);
vec.push_back(root->val); vec.push_back(root->val);
@ -28,40 +30,40 @@ void inOrder(TreeNode* root) {
} }
/* 后序遍历 */ /* 后序遍历 */
void postOrder(TreeNode* root) { void postOrder(TreeNode *root) {
if (root == nullptr) return; if (root == nullptr)
return;
// 访问优先级:左子树 -> 右子树 -> 根节点 // 访问优先级:左子树 -> 右子树 -> 根节点
postOrder(root->left); postOrder(root->left);
postOrder(root->right); postOrder(root->right);
vec.push_back(root->val); vec.push_back(root->val);
} }
/* Driver Code */ /* Driver Code */
int main() { int main() {
/* 初始化二叉树 */ /* 初始化二叉树 */
// 这里借助了一个从数组直接生成二叉树的函数 // 这里借助了一个从数组直接生成二叉树的函数
TreeNode* root = vecToTree(vector<int> { 1, 2, 3, 4, 5, 6, 7 }); TreeNode *root = vecToTree(vector<int>{1, 2, 3, 4, 5, 6, 7});
cout << endl << "初始化二叉树\n" << endl; cout << endl << "初始化二叉树\n" << endl;
PrintUtil::printTree(root); printTree(root);
/* 前序遍历 */ /* 前序遍历 */
vec.clear(); vec.clear();
preOrder(root); preOrder(root);
cout << endl << "前序遍历的节点打印序列 = "; cout << endl << "前序遍历的节点打印序列 = ";
PrintUtil::printVector(vec); printVector(vec);
/* 中序遍历 */ /* 中序遍历 */
vec.clear(); vec.clear();
inOrder(root); inOrder(root);
cout << endl << "中序遍历的节点打印序列 = "; cout << endl << "中序遍历的节点打印序列 = ";
PrintUtil::printVector(vec); printVector(vec);
/* 后序遍历 */ /* 后序遍历 */
vec.clear(); vec.clear();
postOrder(root); postOrder(root);
cout << endl << "后序遍历的节点打印序列 = "; cout << endl << "后序遍历的节点打印序列 = ";
PrintUtil::printVector(vec); printVector(vec);
return 0; return 0;
} }

View File

@ -9,23 +9,16 @@
#include <iostream> #include <iostream>
using namespace std; using namespace std;
/** /* Definition for a singly-linked list node */
* @brief Definition for a singly-linked list node
*
*/
struct ListNode { struct ListNode {
int val; int val;
ListNode *next; ListNode *next;
ListNode(int x) : val(x), next(nullptr) {} ListNode(int x) : val(x), next(nullptr) {
}
}; };
/** /* Generate a linked list with a vector */
* @brief Generate a linked list with a vector ListNode *vecToLinkedList(vector<int> list) {
*
* @param list
* @return ListNode*
*/
ListNode* vecToLinkedList(vector<int> list) {
ListNode *dum = new ListNode(0); ListNode *dum = new ListNode(0);
ListNode *head = dum; ListNode *head = dum;
for (int val : list) { for (int val : list) {
@ -35,25 +28,15 @@ ListNode* vecToLinkedList(vector<int> list) {
return dum->next; return dum->next;
} }
/** /* Get a list node with specific value from a linked list */
* @brief Get a list node with specific value from a linked list ListNode *getListNode(ListNode *head, int val) {
*
* @param head
* @param val
* @return ListNode*
*/
ListNode* getListNode(ListNode *head, int val) {
while (head != nullptr && head->val != val) { while (head != nullptr && head->val != val) {
head = head->next; head = head->next;
} }
return head; return head;
} }
/** /* Free the memory allocated to a linked list */
* @brief Free the memory allocated to a linked list
*
* @param cur
*/
void freeMemoryLinkedList(ListNode *cur) { void freeMemoryLinkedList(ListNode *cur) {
// 释放内存 // 释放内存
ListNode *pre; ListNode *pre;

View File

@ -6,334 +6,224 @@
#pragma once #pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <climits>
#include "ListNode.hpp" #include "ListNode.hpp"
#include "TreeNode.hpp" #include "TreeNode.hpp"
#include <climits>
#include <iostream>
#include <sstream>
#include <string>
/** /* Expose the underlying storage of the priority_queue container */
* @brief Expose the underlying storage of the priority_queue container template <typename T, typename S, typename C> S &Container(priority_queue<T, S, C> &pq) {
* struct HackedQueue : private priority_queue<T, S, C> {
* @tparam T static S &Container(priority_queue<T, S, C> &pq) {
* @tparam S
* @tparam C
* @param pq
* @return S
*/
template <typename T, typename S, typename C>
S &Container(priority_queue<T, S, C> &pq) {
struct HackedQueue : private priority_queue<T, S, C>
{
static S &Container(priority_queue<T, S, C> &pq)
{
return pq.*&HackedQueue::c; return pq.*&HackedQueue::c;
} }
}; };
return HackedQueue::Container(pq); return HackedQueue::Container(pq);
} }
class PrintUtil { /* Find an element in a vector */
public: template <typename T> int vecFind(const vector<T> &vec, T ele) {
/** int j = INT_MAX;
* @brief Find an element in a vector for (int i = 0; i < vec.size(); i++) {
* if (vec[i] == ele) {
* @tparam T j = i;
* @param vec
* @param ele
* @return int
*/
template <typename T>
static int vecFind(const vector<T>& vec, T ele) {
int j = INT_MAX;
for (int i = 0; i < vec.size(); i++) {
if (vec[i] == ele) {
j = i;
}
}
return j;
} }
}
return j;
}
/** /* Concatenate a vector with a delim */
* @brief Concatenate a vector with a delim template <typename T> string strJoin(const string &delim, const T &vec) {
* ostringstream s;
* @tparam T for (const auto &i : vec) {
* @param delim if (&i != &vec[0]) {
* @param vec s << delim;
* @return string
*/
template <typename T>
static string strJoin(const string& delim, const T& vec) {
ostringstream s;
for (const auto& i : vec) {
if (&i != &vec[0]) {
s << delim;
}
s << i;
}
return s.str();
} }
s << i;
}
return s.str();
}
/** /* Repeat a string for n times */
* @brief Repeat a string for n times string strRepeat(string str, int n) {
* ostringstream os;
* @param str for (int i = 0; i < n; i++)
* @param n os << str;
* @return string return os.str();
*/ }
static string strRepeat(string str, int n) {
ostringstream os;
for(int i = 0; i < n; i++)
os << str;
return os.str();
}
/** /* Print an Array */
* @brief Print an Array template <typename T> void printArray(T *arr, int n) {
* cout << "[";
* @tparam T for (int i = 0; i < n - 1; i++) {
* @tparam n cout << arr[i] << ", ";
*/ }
template<typename T> if (n >= 1)
static void printArray(T* arr, int n) cout << arr[n - 1] << "]" << endl;
{ else
cout << "["; cout << "]" << endl;
for (int i = 0; i < n - 1; i++) { }
cout << arr[i] << ", ";
}
if (n >= 1)
cout << arr[n - 1] << "]" << endl;
else
cout << "]" << endl;
}
/** /* Get the Vector String object */
* @brief Get the Vector String object template <typename T> string getVectorString(vector<T> &list) {
* return "[" + strJoin(", ", list) + "]";
* @tparam T }
* @param list
* @return string
*/
template <typename T>
static string getVectorString(vector<T> &list) {
return "[" + strJoin(", ", list) + "]";
}
/** /* Print a vector */
* @brief Print a vector template <typename T> void printVector(vector<T> list) {
* cout << getVectorString(list) << '\n';
* @tparam T }
* @param list
*/
template <typename T>
static void printVector(vector<T> list) {
cout << getVectorString(list) << '\n';
}
/** /* Print a vector matrix */
* @brief Print a vector matrix template <typename T> void printVectorMatrix(vector<vector<T>> &matrix) {
* cout << "[" << '\n';
* @tparam T for (vector<T> &list : matrix)
* @param matrix cout << " " + getVectorString(list) + "," << '\n';
*/ cout << "]" << '\n';
template <typename T> }
static void printVectorMatrix(vector<vector<T>> &matrix) {
cout << "[" << '\n';
for (vector<T> &list : matrix)
cout << " " + getVectorString(list) + "," << '\n';
cout << "]" << '\n';
}
/** /* Print a linked list */
* @brief Print a linked list void printLinkedList(ListNode *head) {
* vector<int> list;
* @param head while (head != nullptr) {
*/ list.push_back(head->val);
static void printLinkedList(ListNode *head) { head = head->next;
vector<int> list; }
while (head != nullptr) {
list.push_back(head->val);
head = head->next;
}
cout << strJoin(" -> ", list) << '\n';
}
/** cout << strJoin(" -> ", list) << '\n';
* @brief This tree printer is borrowed from TECHIE DELIGHT }
* https://www.techiedelight.com/c-program-print-binary-tree/
*/
struct Trunk {
Trunk *prev;
string str;
Trunk(Trunk *prev, string str) {
this->prev = prev;
this->str = str;
}
};
/**
* @brief Helper function to print branches of the binary tree
*
* @param p
*/
static void showTrunks(Trunk *p) {
if (p == nullptr) {
return;
}
showTrunks(p->prev);
cout << p->str;
}
/** /**
* @brief The interface of the tree printer * This tree printer is borrowed from TECHIE DELIGHT
* * https://www.techiedelight.com/c-program-print-binary-tree/
* @param root */
*/ struct Trunk {
static void printTree(TreeNode *root) { Trunk *prev;
printTree(root, nullptr, false); string str;
} Trunk(Trunk *prev, string str) {
this->prev = prev;
/** this->str = str;
* @brief Print a binary tree }
*
* @param root
* @param prev
* @param isLeft
*/
static void printTree(TreeNode *root, Trunk *prev, bool isLeft) {
if (root == nullptr) {
return;
}
string prev_str = " ";
Trunk trunk(prev, prev_str);
printTree(root->right, &trunk, true);
if (!prev) {
trunk.str = "———";
}
else if (isLeft) {
trunk.str = "/———";
prev_str = " |";
}
else {
trunk.str = "\\———";
prev->str = prev_str;
}
showTrunks(&trunk);
cout << " " << root->val << endl;
if (prev) {
prev->str = prev_str;
}
trunk.str = " |";
printTree(root->left, &trunk, false);
}
/**
* @brief Print a stack
*
* @tparam T
* @param stk
*/
template <typename T>
static void printStack(stack<T> stk) {
// Reverse the input stack
stack<T> tmp;
while(!stk.empty()) {
tmp.push(stk.top());
stk.pop();
}
// Generate the string to print
ostringstream s;
bool flag = true;
while(!tmp.empty()) {
if (flag) {
s << tmp.top();
flag = false;
}
else s << ", " << tmp.top();
tmp.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
/**
* @brief
*
* @tparam T
* @param queue
*/
template <typename T>
static void printQueue(queue<T> queue)
{
// Generate the string to print
ostringstream s;
bool flag = true;
while(!queue.empty()) {
if (flag) {
s << queue.front();
flag = false;
}
else s << ", " << queue.front();
queue.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
template <typename T>
static void printDeque(deque<T> deque) {
// Generate the string to print
ostringstream s;
bool flag = true;
while(!deque.empty()) {
if (flag) {
s << deque.front();
flag = false;
}
else s << ", " << deque.front();
deque.pop_front();
}
cout << "[" + s.str() + "]" << '\n';
}
/**
* @brief Print a HashMap
*
* @tparam TKey
* @tparam TValue
* @param map
*/
// 定义模板参数 TKey 和 TValue用于指定键值对的类型
template <typename TKey, typename TValue>
static void printHashMap(unordered_map<TKey,TValue> map) {
for (auto kv : map) {
cout << kv.first << " -> " << kv.second << '\n';
}
}
/**
* @brief Print a Heap (PriorityQueue)
*
* @tparam T
* @tparam S
* @tparam C
* @param heap
*/
template <typename T, typename S, typename C>
static void printHeap(priority_queue<T, S, C> &heap) {
vector<T> vec = Container(heap);
cout << "堆的数组表示:";
printVector(vec);
cout << "堆的树状表示:" << endl;
TreeNode *root = vecToTree(vec);
printTree(root);
freeMemoryTree(root);
}
}; };
/* Helper function to print branches of the binary tree */
void showTrunks(Trunk *p) {
if (p == nullptr) {
return;
}
showTrunks(p->prev);
cout << p->str;
}
/* Print a binary tree */
void printTree(TreeNode *root, Trunk *prev, bool isLeft) {
if (root == nullptr) {
return;
}
string prev_str = " ";
Trunk trunk(prev, prev_str);
printTree(root->right, &trunk, true);
if (!prev) {
trunk.str = "———";
} else if (isLeft) {
trunk.str = "/———";
prev_str = " |";
} else {
trunk.str = "\\———";
prev->str = prev_str;
}
showTrunks(&trunk);
cout << " " << root->val << endl;
if (prev) {
prev->str = prev_str;
}
trunk.str = " |";
printTree(root->left, &trunk, false);
}
/* The interface of the tree printer */
void printTree(TreeNode *root) {
printTree(root, nullptr, false);
}
/* Print a stack */
template <typename T> void printStack(stack<T> stk) {
// Reverse the input stack
stack<T> tmp;
while (!stk.empty()) {
tmp.push(stk.top());
stk.pop();
}
// Generate the string to print
ostringstream s;
bool flag = true;
while (!tmp.empty()) {
if (flag) {
s << tmp.top();
flag = false;
} else
s << ", " << tmp.top();
tmp.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
/* Print a queue */
template <typename T> void printQueue(queue<T> queue) {
// Generate the string to print
ostringstream s;
bool flag = true;
while (!queue.empty()) {
if (flag) {
s << queue.front();
flag = false;
} else
s << ", " << queue.front();
queue.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
/* Print a deque */
template <typename T> void printDeque(deque<T> deque) {
// Generate the string to print
ostringstream s;
bool flag = true;
while (!deque.empty()) {
if (flag) {
s << deque.front();
flag = false;
} else
s << ", " << deque.front();
deque.pop_front();
}
cout << "[" + s.str() + "]" << '\n';
}
/* Print a HashMap */
// 定义模板参数 TKey 和 TValue用于指定键值对的类型
template <typename TKey, typename TValue> void printHashMap(unordered_map<TKey, TValue> map) {
for (auto kv : map) {
cout << kv.first << " -> " << kv.second << '\n';
}
}
/* Print a Heap (PriorityQueue) */
template <typename T, typename S, typename C> void printHeap(priority_queue<T, S, C> &heap) {
vector<T> vec = Container(heap);
cout << "堆的数组表示:";
printVector(vec);
cout << "堆的树状表示:" << endl;
TreeNode *root = vecToTree(vec);
printTree(root);
freeMemoryTree(root);
}

View File

@ -6,10 +6,7 @@
#pragma once #pragma once
/** /* Definition for a binary tree node */
* @brief Definition for a binary tree node
*
*/
struct TreeNode { struct TreeNode {
int val{}; int val{};
int height = 0; int height = 0;
@ -17,15 +14,11 @@ struct TreeNode {
TreeNode *left{}; TreeNode *left{};
TreeNode *right{}; TreeNode *right{};
TreeNode() = default; TreeNode() = default;
explicit TreeNode(int x, TreeNode *parent = nullptr) : val(x), parent(parent) {} explicit TreeNode(int x, TreeNode *parent = nullptr) : val(x), parent(parent) {
}
}; };
/** /* Generate a binary tree with a vector */
* @brief Generate a binary tree with a vector
*
* @param list
* @return TreeNode*
*/
TreeNode *vecToTree(vector<int> list) { TreeNode *vecToTree(vector<int> list) {
if (list.empty()) if (list.empty())
return nullptr; return nullptr;
@ -37,12 +30,14 @@ TreeNode *vecToTree(vector<int> list) {
while (!que.empty()) { while (!que.empty()) {
auto node = que.front(); auto node = que.front();
que.pop(); que.pop();
if (++index >= n) break; if (++index >= n)
break;
if (index < n) { if (index < n) {
node->left = new TreeNode(list[index]); node->left = new TreeNode(list[index]);
que.emplace(node->left); que.emplace(node->left);
} }
if (++index >= n) break; if (++index >= n)
break;
if (index < n) { if (index < n) {
node->right = new TreeNode(list[index]); node->right = new TreeNode(list[index]);
que.emplace(node->right); que.emplace(node->right);
@ -52,13 +47,7 @@ TreeNode *vecToTree(vector<int> list) {
return root; return root;
} }
/** /* Get a tree node with specific value in a binary tree */
* @brief Get a tree node with specific value in a binary tree
*
* @param root
* @param val
* @return TreeNode*
*/
TreeNode *getTreeNode(TreeNode *root, int val) { TreeNode *getTreeNode(TreeNode *root, int val) {
if (root == nullptr) if (root == nullptr)
return nullptr; return nullptr;
@ -69,15 +58,12 @@ TreeNode *getTreeNode(TreeNode *root, int val) {
return left != nullptr ? left : right; return left != nullptr ? left : right;
} }
/** /* Free the memory allocated to a tree */
* @brief Free the memory allocated to a tree
*
* @param root
*/
void freeMemoryTree(TreeNode *root) { void freeMemoryTree(TreeNode *root) {
if (root == nullptr) return; if (root == nullptr)
freeMemoryTree(root->left); return;
freeMemoryTree(root->left);
freeMemoryTree(root->right); freeMemoryTree(root->right);
// 释放内存 // 释放内存
delete root; delete root;
} }

View File

@ -12,12 +12,13 @@ using namespace std;
/* 顶点类 */ /* 顶点类 */
struct Vertex { struct Vertex {
int val; int val;
Vertex(int x) : val(x) {} Vertex(int x) : val(x) {
}
}; };
/* 输入值列表 vals ,返回顶点列表 vets */ /* 输入值列表 vals ,返回顶点列表 vets */
vector<Vertex*> valsToVets(vector<int> vals) { vector<Vertex *> valsToVets(vector<int> vals) {
vector<Vertex*> vets; vector<Vertex *> vets;
for (int val : vals) { for (int val : vals) {
vets.push_back(new Vertex(val)); vets.push_back(new Vertex(val));
} }
@ -25,7 +26,7 @@ vector<Vertex*> valsToVets(vector<int> vals) {
} }
/* 输入顶点列表 vets ,返回值列表 vals */ /* 输入顶点列表 vets ,返回值列表 vals */
vector<int> vetsToVals(vector<Vertex*> vets) { vector<int> vetsToVals(vector<Vertex *> vets) {
vector<int> vals; vector<int> vals;
for (Vertex *vet : vets) { for (Vertex *vet : vets) {
vals.push_back(vet->val); vals.push_back(vet->val);

View File

@ -6,23 +6,23 @@
#pragma once #pragma once
#include <iostream> #include <algorithm>
#include <string> #include <chrono>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque> #include <deque>
#include <iostream>
#include <list>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <set> #include <vector>
#include <random>
#include <chrono>
#include <algorithm>
#include "ListNode.hpp" #include "ListNode.hpp"
#include "PrintUtil.hpp"
#include "TreeNode.hpp" #include "TreeNode.hpp"
#include "Vertex.hpp" #include "Vertex.hpp"
#include "PrintUtil.hpp"
using namespace std; using namespace std;