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

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

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp"
/* 随机返回一个数组元素 */
int randomAccess(int* nums, int size) {
int randomAccess(int *nums, int size) {
// 在区间 [0, 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++) {
res[i] = nums[i];
@ -30,7 +30,7 @@ int* extend(int* nums, int size, int enlarge) {
}
/* 在数组的索引 index 处插入元素 num */
void insert(int* nums, int size, int num, int index) {
void insert(int *nums, int size, int num, int index) {
// 把索引 index 以及之后的所有元素向后移动一位
for (int i = size - 1; i > index; i--) {
nums[i] = nums[i - 1];
@ -40,7 +40,7 @@ void insert(int* nums, int size, int num, int index) {
}
/* 删除索引 index 处元素 */
void remove(int* nums, int size, int index) {
void remove(int *nums, int size, int index) {
// 把索引 index 之后的所有元素向前移动一位
for (int i = index; i < size - 1; i++) {
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;
// 通过索引遍历数组
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++) {
if (nums[i] == target)
return i;
@ -65,18 +65,17 @@ int find(int* nums, int size, int target) {
return -1;
}
/* Driver Code */
int main() {
/* 初始化数组 */
int size = 5;
int* arr = new int[size];
int *arr = new int[size];
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 = ";
PrintUtil::printArray(nums, size);
printArray(nums, size);
/* 随机访问 */
int randomNum = randomAccess(nums, size);
@ -87,17 +86,17 @@ int main() {
nums = extend(nums, size, enlarge);
size += enlarge;
cout << "将数组长度扩展至 8 ,得到 nums = ";
PrintUtil::printArray(nums, size);
printArray(nums, size);
/* 插入元素 */
insert(nums, size, 6, 3);
cout << "在索引 3 处插入数字 6 ,得到 nums = ";
PrintUtil::printArray(nums, size);
printArray(nums, size);
/* 删除元素 */
remove(nums, size, 2);
cout << "删除索引 2 处的元素,得到 nums = ";
PrintUtil::printArray(nums, size);
printArray(nums, size);
/* 遍历数组 */
traverse(nums, size);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,13 +9,13 @@
/* 广度优先遍历 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
queue<Vertex*> que;
queue<Vertex *> que;
que.push(startVet);
// 以顶点 vet 为起点,循环直至访问完所有顶点
while (!que.empty()) {
@ -37,18 +37,18 @@ vector<Vertex*> graphBFS(GraphAdjList &graph, Vertex *startVet) {
/* Driver Code */
int main() {
/* 初始化无向图 */
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] },
{ 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] } };
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]},
{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]}};
GraphAdjList graph(edges);
cout << "\n初始化后,图为\\n";
graph.print();
/* 广度优先遍历 BFS */
vector<Vertex*> res = graphBFS(graph, v[0]);
vector<Vertex *> res = graphBFS(graph, v[0]);
cout << "\n广度优先遍历BFS顶点序列为" << endl;
PrintUtil::printVector(vetsToVals(res));
printVector(vetsToVals(res));
// 释放内存
for (Vertex *vet : v) {

View File

@ -8,11 +8,11 @@
#include "./graph_adjacency_list.cpp"
/* 深度优先遍历 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); // 记录访问顶点
visited.emplace(vet); // 标记该顶点已被访问
// 遍历该顶点的所有邻接顶点
for (Vertex* adjVet : graph.adjList[vet]) {
for (Vertex *adjVet : graph.adjList[vet]) {
if (visited.count(adjVet))
continue; // 跳过已被访问过的顶点
// 递归访问邻接顶点
@ -22,11 +22,11 @@ void dfs(GraphAdjList& graph, unordered_set<Vertex*>& visited, vector<Vertex*>&
/* 深度优先遍历 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);
return res;
}
@ -34,17 +34,17 @@ vector<Vertex*> graphDFS(GraphAdjList& graph, Vertex* startVet) {
/* Driver Code */
int main() {
/* 初始化无向图 */
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] },
{ v[2], v[5] }, { v[4], v[5] }, { v[5], v[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]},
{v[2], v[5]}, {v[4], v[5]}, {v[5], v[6]}};
GraphAdjList graph(edges);
cout << "\n初始化后,图为" << endl;
graph.print();
/* 深度优先遍历 DFS */
vector<Vertex*> res = graphDFS(graph, v[0]);
vector<Vertex *> res = graphDFS(graph, v[0]);
cout << "\n深度优先遍历DFS顶点序列为" << endl;
PrintUtil::printVector(vetsToVals(res));
printVector(vetsToVals(res));
// 释放内存
for (Vertex *vet : v) {

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@
/* 大顶堆 */
class MaxHeap {
private:
private:
// 使用动态数组,这样无需考虑扩容问题
vector<int> maxHeap;
@ -61,7 +61,7 @@ private:
}
}
public:
public:
/* 构造方法,根据输入列表建堆 */
MaxHeap(vector<int> nums) {
// 将列表元素原封不动添加进堆
@ -112,15 +112,14 @@ public:
/* 打印堆(二叉树)*/
void print() {
cout << "堆的数组表示:";
PrintUtil::printVector(maxHeap);
printVector(maxHeap);
cout << "堆的树状表示:" << endl;
TreeNode *root = vecToTree(maxHeap);
PrintUtil::printTree(root);
printTree(root);
freeMemoryTree(root);
}
};
/* Driver Code */
int main() {
/* 初始化大顶堆 */

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp"
/* 二分查找(双闭区间) */
int binarySearch(vector<int>& nums, int target) {
int binarySearch(vector<int> &nums, int target) {
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
int i = 0, j = nums.size() - 1;
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
@ -25,7 +25,7 @@ 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
int i = 0, j = nums.size();
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
@ -42,11 +42,10 @@ int binarySearch1(vector<int>& nums, int target) {
return -1;
}
/* Driver Code */
int main() {
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);

View File

@ -16,7 +16,7 @@ int hashingSearchArray(unordered_map<int, int> map, int target) {
}
/* 哈希查找(链表) */
ListNode* hashingSearchLinkedList(unordered_map<int, ListNode*> map, int target) {
ListNode *hashingSearchLinkedList(unordered_map<int, ListNode *> map, int target) {
// 哈希表的 key: 目标节点值value: 节点对象
// 若哈希表中无此 key ,返回 nullptr
if (map.find(target) == map.end())
@ -24,13 +24,12 @@ ListNode* hashingSearchLinkedList(unordered_map<int, ListNode*> map, int target)
return map[target];
}
/* Driver Code */
int main() {
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;
for (int i = 0; i < nums.size(); i++) {
@ -40,14 +39,14 @@ int main() {
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) {
map1[head->val] = head; // key: 节点值value: 节点
head = head->next;
}
ListNode* node = hashingSearchLinkedList(map1, target);
ListNode *node = hashingSearchLinkedList(map1, target);
cout << "目标节点值 3 的对应节点对象为 " << node << endl;
return 0;

View File

@ -7,7 +7,7 @@
#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++) {
// 找到目标元素,返回其索引
@ -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) {
// 找到目标节点,返回之
@ -31,19 +31,18 @@ ListNode* linearSearchLinkedList(ListNode* head, int target) {
return nullptr;
}
/* Driver Code */
int main() {
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);
cout << "目标元素 3 的索引 = " << index << endl;
/* 在链表中执行线性查找 */
ListNode* head = vecToLinkedList(nums);
ListNode* node = linearSearchLinkedList(head, target);
ListNode *head = vecToLinkedList(nums);
ListNode *node = linearSearchLinkedList(head, target);
cout << "目标节点值 3 的对应节点对象为 " << node << endl;
return 0;

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp"
/* 冒泡排序 */
void bubbleSort(vector<int>& nums) {
void bubbleSort(vector<int> &nums) {
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
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
for (int i = nums.size() - 1; i > 0; i--) {
bool flag = false; // 初始化标志位
@ -35,22 +35,22 @@ void bubbleSortWithFlag(vector<int>& nums) {
flag = true; // 记录交换元素
}
}
if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出
if (!flag)
break; // 此轮冒泡未交换任何元素,直接跳出
}
}
/* Driver Code */
int main() {
vector<int> nums = { 4, 1, 3, 1, 5, 2 };
vector<int> nums = {4, 1, 3, 1, 5, 2};
bubbleSort(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);
cout << "冒泡排序完成后 nums1 = ";
PrintUtil::printVector(nums1);
printVector(nums1);
return 0;
}

View File

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

View File

@ -8,7 +8,7 @@
/* 计数排序 */
// 简单实现,无法用于排序对象
void countingSortNaive(vector<int>& nums) {
void countingSortNaive(vector<int> &nums) {
// 1. 统计数组最大元素 m
int m = 0;
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
int m = 0;
for (int num : nums) {
@ -63,15 +63,15 @@ void countingSort(vector<int>& nums) {
/* Driver Code */
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);
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);
cout << "计数排序完成后 nums1 = ";
PrintUtil::printVector(nums1);
printVector(nums1);
return 0;
}

View File

@ -7,7 +7,7 @@
#include "../include/include.hpp"
/* 插入排序 */
void insertionSort(vector<int>& nums) {
void insertionSort(vector<int> &nums) {
// 外循环base = nums[1], nums[2], ..., nums[n-1]
for (int i = 1; i < nums.size(); i++) {
int base = nums[i], j = i - 1;
@ -20,13 +20,12 @@ void insertionSort(vector<int>& nums) {
}
}
/* Driver Code */
int main() {
vector<int> nums = { 4, 1, 3, 1, 5, 2 };
vector<int> nums = {4, 1, 3, 1, 5, 2};
insertionSort(nums);
cout << "插入排序完成后 nums = ";
PrintUtil::printVector(nums);
printVector(nums);
return 0;
}

View File

@ -9,7 +9,7 @@
/* 合并左子数组和右子数组 */
// 左子数组区间 [left, mid]
// 右子数组区间 [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);
// 左子数组的起始索引和结束索引
@ -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; // 计算中点
mergeSort(nums, left, mid); // 递归左子数组
@ -44,14 +45,13 @@ void mergeSort(vector<int>& nums, int left, int right) {
merge(nums, left, mid, right);
}
/* Driver Code */
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);
cout << "归并排序完成后 nums = ";
PrintUtil::printVector(nums);
printVector(nums);
return 0;
}

View File

@ -8,16 +8,16 @@
/* 快速排序类 */
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];
nums[i] = nums[j];
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] 作为基准数
int i = left, j = right;
while (i < j) {
@ -31,9 +31,9 @@ private:
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 时终止递归
if (left >= right)
return;
@ -47,16 +47,16 @@ public:
/* 快速排序类(中位基准数优化) */
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];
nums[i] = nums[j];
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
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);
// 将中位数交换至数组最左端
@ -86,9 +86,9 @@ private:
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 时终止递归
if (left >= right)
return;
@ -102,16 +102,16 @@ public:
/* 快速排序类(尾递归优化) */
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];
nums[i] = nums[j];
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] 作为基准数
int i = left, j = right;
while (i < j) {
@ -125,9 +125,9 @@ private:
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 时终止
while (left < right) {
// 哨兵划分操作
@ -144,26 +144,25 @@ public:
}
};
/* Driver Code */
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);
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);
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);
cout << "快速排序(尾递归优化)完成后 nums = ";
PrintUtil::printVector(nums);
printVector(nums);
return 0;
}

View File

@ -14,7 +14,7 @@ int digit(int num, int exp) {
}
/* 计数排序(根据 nums 第 k 位排序) */
void countingSortDigit(vector<int>& nums, int exp) {
void countingSortDigit(vector<int> &nums, int exp) {
// 十进制的位范围为 0~9 ,因此需要长度为 10 的桶
vector<int> counter(10, 0);
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());
// 按照从低位到高位的顺序遍历
@ -56,11 +56,11 @@ void radixSort(vector<int>& nums) {
/* Driver Code */
int main() {
// 基数排序
vector<int> nums = { 10546151, 35663510, 42865989, 34862445, 81883077,
88906420, 72429244, 30524779, 82060337, 63832996 };
vector<int> nums = {10546151, 35663510, 42865989, 34862445, 81883077,
88906420, 72429244, 30524779, 82060337, 63832996};
radixSort(nums);
cout << "基数排序完成后 nums = ";
PrintUtil::printVector(nums);
printVector(nums);
return 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,9 +6,8 @@
#include "../include/include.hpp"
/* Driver Code */
int main(){
int main() {
/* 初始化队列 */
queue<int> queue;
@ -19,7 +18,7 @@ int main(){
queue.push(5);
queue.push(4);
cout << "队列 queue = ";
PrintUtil::printQueue(queue);
printQueue(queue);
/* 访问队首元素 */
int front = queue.front();
@ -28,7 +27,7 @@ int main(){
/* 元素出队 */
queue.pop();
cout << "出队元素 front = " << front << ",出队后 queue = ";
PrintUtil::printQueue(queue);
printQueue(queue);
/* 获取队列的长度 */
int size = queue.size();

View File

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

View File

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

View File

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

View File

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

View File

@ -7,14 +7,14 @@
#include "../include/include.hpp"
/* 层序遍历 */
vector<int> levelOrder(TreeNode* root) {
vector<int> levelOrder(TreeNode *root) {
// 初始化队列,加入根节点
queue<TreeNode*> queue;
queue<TreeNode *> queue;
queue.push(root);
// 初始化一个列表,用于保存遍历序列
vector<int> vec;
while (!queue.empty()) {
TreeNode* node = queue.front();
TreeNode *node = queue.front();
queue.pop(); // 队列出队
vec.push_back(node->val); // 保存节点值
if (node->left != nullptr)
@ -25,19 +25,18 @@ vector<int> levelOrder(TreeNode* root) {
return vec;
}
/* Driver Code */
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;
PrintUtil::printTree(root);
printTree(root);
/* 层序遍历 */
vector<int> vec = levelOrder(root);
cout << endl << "层序遍历的节点打印序列 = ";
PrintUtil::printVector(vec);
printVector(vec);
return 0;
}

View File

@ -10,8 +10,9 @@
vector<int> vec;
/* 前序遍历 */
void preOrder(TreeNode* root) {
if (root == nullptr) return;
void preOrder(TreeNode *root) {
if (root == nullptr)
return;
// 访问优先级:根节点 -> 左子树 -> 右子树
vec.push_back(root->val);
preOrder(root->left);
@ -19,8 +20,9 @@ void preOrder(TreeNode* root) {
}
/* 中序遍历 */
void inOrder(TreeNode* root) {
if (root == nullptr) return;
void inOrder(TreeNode *root) {
if (root == nullptr)
return;
// 访问优先级:左子树 -> 根节点 -> 右子树
inOrder(root->left);
vec.push_back(root->val);
@ -28,40 +30,40 @@ void inOrder(TreeNode* root) {
}
/* 后序遍历 */
void postOrder(TreeNode* root) {
if (root == nullptr) return;
void postOrder(TreeNode *root) {
if (root == nullptr)
return;
// 访问优先级:左子树 -> 右子树 -> 根节点
postOrder(root->left);
postOrder(root->right);
vec.push_back(root->val);
}
/* Driver Code */
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;
PrintUtil::printTree(root);
printTree(root);
/* 前序遍历 */
vec.clear();
preOrder(root);
cout << endl << "前序遍历的节点打印序列 = ";
PrintUtil::printVector(vec);
printVector(vec);
/* 中序遍历 */
vec.clear();
inOrder(root);
cout << endl << "中序遍历的节点打印序列 = ";
PrintUtil::printVector(vec);
printVector(vec);
/* 后序遍历 */
vec.clear();
postOrder(root);
cout << endl << "后序遍历的节点打印序列 = ";
PrintUtil::printVector(vec);
printVector(vec);
return 0;
}

View File

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

View File

@ -6,46 +6,25 @@
#pragma once
#include <iostream>
#include <string>
#include <sstream>
#include <climits>
#include "ListNode.hpp"
#include "TreeNode.hpp"
#include <climits>
#include <iostream>
#include <sstream>
#include <string>
/**
* @brief Expose the underlying storage of the priority_queue container
*
* @tparam T
* @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)
{
/* 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> {
static S &Container(priority_queue<T, S, C> &pq) {
return pq.*&HackedQueue::c;
}
};
return HackedQueue::Container(pq);
}
class PrintUtil {
public:
/**
* @brief Find an element in a vector
*
* @tparam T
* @param vec
* @param ele
* @return int
*/
template <typename T>
static int vecFind(const vector<T>& vec, T ele) {
/* Find an element in a vector */
template <typename T> int vecFind(const vector<T> &vec, T ele) {
int j = INT_MAX;
for (int i = 0; i < vec.size(); i++) {
if (vec[i] == ele) {
@ -53,51 +32,30 @@ class PrintUtil {
}
}
return j;
}
}
/**
* @brief Concatenate a vector with a delim
*
* @tparam T
* @param delim
* @param vec
* @return string
*/
template <typename T>
static string strJoin(const string& delim, const T& vec) {
/* Concatenate a vector with a delim */
template <typename T> string strJoin(const string &delim, const T &vec) {
ostringstream s;
for (const auto& i : vec) {
for (const auto &i : vec) {
if (&i != &vec[0]) {
s << delim;
}
s << i;
}
return s.str();
}
}
/**
* @brief Repeat a string for n times
*
* @param str
* @param n
* @return string
*/
static string strRepeat(string str, int n) {
/* Repeat a string for n times */
string strRepeat(string str, int n) {
ostringstream os;
for(int i = 0; i < n; i++)
for (int i = 0; i < n; i++)
os << str;
return os.str();
}
}
/**
* @brief Print an Array
*
* @tparam T
* @tparam n
*/
template<typename T>
static void printArray(T* arr, int n)
{
/* Print an Array */
template <typename T> void printArray(T *arr, int n) {
cout << "[";
for (int i = 0; i < n - 1; i++) {
cout << arr[i] << ", ";
@ -106,51 +64,28 @@ class PrintUtil {
cout << arr[n - 1] << "]" << endl;
else
cout << "]" << endl;
}
}
/**
* @brief Get the Vector String object
*
* @tparam T
* @param list
* @return string
*/
template <typename T>
static string getVectorString(vector<T> &list) {
/* Get the Vector String object */
template <typename T> string getVectorString(vector<T> &list) {
return "[" + strJoin(", ", list) + "]";
}
}
/**
* @brief Print a vector
*
* @tparam T
* @param list
*/
template <typename T>
static void printVector(vector<T> list) {
/* Print a vector */
template <typename T> void printVector(vector<T> list) {
cout << getVectorString(list) << '\n';
}
}
/**
* @brief Print a vector matrix
*
* @tparam T
* @param matrix
*/
template <typename T>
static void printVectorMatrix(vector<vector<T>> &matrix) {
/* Print a vector matrix */
template <typename T> void printVectorMatrix(vector<vector<T>> &matrix) {
cout << "[" << '\n';
for (vector<T> &list : matrix)
cout << " " + getVectorString(list) + "," << '\n';
cout << "]" << '\n';
}
}
/**
* @brief Print a linked list
*
* @param head
*/
static void printLinkedList(ListNode *head) {
/* Print a linked list */
void printLinkedList(ListNode *head) {
vector<int> list;
while (head != nullptr) {
list.push_back(head->val);
@ -158,52 +93,33 @@ class PrintUtil {
}
cout << strJoin(" -> ", list) << '\n';
}
}
/**
* @brief This tree printer is borrowed from TECHIE DELIGHT
/**
* This tree printer is borrowed from TECHIE DELIGHT
* https://www.techiedelight.com/c-program-print-binary-tree/
*/
struct Trunk {
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) {
/* Helper function to print branches of the binary tree */
void showTrunks(Trunk *p) {
if (p == nullptr) {
return;
}
showTrunks(p->prev);
cout << p->str;
}
}
/**
* @brief The interface of the tree printer
*
* @param root
*/
static void printTree(TreeNode *root) {
printTree(root, nullptr, false);
}
/**
* @brief Print a binary tree
*
* @param root
* @param prev
* @param isLeft
*/
static void printTree(TreeNode *root, Trunk *prev, bool isLeft) {
/* Print a binary tree */
void printTree(TreeNode *root, Trunk *prev, bool isLeft) {
if (root == nullptr) {
return;
}
@ -215,12 +131,10 @@ class PrintUtil {
if (!prev) {
trunk.str = "———";
}
else if (isLeft) {
} else if (isLeft) {
trunk.str = "/———";
prev_str = " |";
}
else {
} else {
trunk.str = "\\———";
prev->str = prev_str;
}
@ -234,100 +148,77 @@ class PrintUtil {
trunk.str = " |";
printTree(root->left, &trunk, false);
}
}
/**
* @brief Print a stack
*
* @tparam T
* @param stk
*/
template <typename T>
static void printStack(stack<T> stk) {
/* 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()) {
while (!stk.empty()) {
tmp.push(stk.top());
stk.pop();
}
// Generate the string to print
ostringstream s;
bool flag = true;
while(!tmp.empty()) {
while (!tmp.empty()) {
if (flag) {
s << tmp.top();
flag = false;
}
else s << ", " << tmp.top();
} else
s << ", " << tmp.top();
tmp.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
}
/**
* @brief
*
* @tparam T
* @param queue
*/
template <typename T>
static void printQueue(queue<T> queue)
{
/* Print a queue */
template <typename T> void printQueue(queue<T> queue) {
// Generate the string to print
ostringstream s;
bool flag = true;
while(!queue.empty()) {
while (!queue.empty()) {
if (flag) {
s << queue.front();
flag = false;
}
else s << ", " << queue.front();
} else
s << ", " << queue.front();
queue.pop();
}
cout << "[" + s.str() + "]" << '\n';
}
}
template <typename T>
static void printDeque(deque<T> deque) {
/* Print a deque */
template <typename T> void printDeque(deque<T> deque) {
// Generate the string to print
ostringstream s;
bool flag = true;
while(!deque.empty()) {
while (!deque.empty()) {
if (flag) {
s << deque.front();
flag = false;
}
else s << ", " << deque.front();
} 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) {
/* 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';
}
}
}
/**
* @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) {
/* 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);
@ -335,5 +226,4 @@ class PrintUtil {
TreeNode *root = vecToTree(vec);
printTree(root);
freeMemoryTree(root);
}
};
}

View File

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

View File

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

View File

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