mirror of
https://github.com/krahets/hello-algo.git
synced 2025-02-02 22:43:50 +08:00
Format C++ codes in Clang-Format Style: Microsoft
This commit is contained in:
parent
f8513455b5
commit
9c9c8b7574
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/* 查找节点 */
|
/* 查找节点 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
// 释放内存
|
// 释放内存
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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() {
|
||||||
/* 初始化大顶堆 */
|
/* 初始化大顶堆 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 释放内存
|
// 释放内存
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user