This commit is contained in:
2025-09-15 21:12:04 +08:00
commit 3f58f483ff
144 changed files with 5298 additions and 0 deletions

35
dataStruct/Combination.h Normal file
View File

@@ -0,0 +1,35 @@
//
// Created by 李洋 on 2023/10/19.
//
#ifndef LEECODE_C_COMBINATION_H
#define LEECODE_C_COMBINATION_H
#include <iostream>
#include <vector>
// 计算组合数 C(n, m)
int calculateCnm(int n, int m) {
if (m < 0 || m > n) {
return 0;
}
if (m > n / 2) {
m = n - m; // 优化,使用较小的 m 提高效率
}
std::vector<std::vector<int>> dp(n + 1, std::vector<int>(m + 1, 0));
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= std::min(i, m); j++) {
if (j == 0 || j == i) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}
}
}
return dp[n][m];
}
#endif //LEECODE_C_COMBINATION_H

23
dataStruct/Heap/Heap.h Normal file
View File

@@ -0,0 +1,23 @@
//
// Created by 李洋 on 2023/8/12.
//
#ifndef LEECODE_C_HEAP_H
#define LEECODE_C_HEAP_H
#include "vector"
template<typename T>
class Heap {
private:
std::vector<T> array;
public:
int length;
Heap(std::vector<T> &array) : array(array){
length = array.size();
}
typedef void (Heap::*compare(T a,T b))(bool);
};
#endif //LEECODE_C_HEAP_H

View File

@@ -0,0 +1,66 @@
//
// Created by 李洋 on 2023/8/6.
//
#ifndef LEECODE_C_LISTS_H
#define LEECODE_C_LISTS_H
#pragma once
#include <iostream>
#include <random>
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
void list() {
ListNode *temp = this;
while (temp) {
std::cout << temp->val << " ";
temp = temp->next;
}
std::cout << std::endl;
}
int *array() {
int *array = new int[len()];
ListNode *temp = this;
int index = 0;
while (temp) {
array[index++] = temp->val;
temp = temp->next;
}
return array;
}
int len() {
int length = 0;
ListNode *temp = this;
while (temp) {
temp = temp->next;
length++;
}
return length;
}
};
ListNode *createRandomList(int len) {
ListNode *p = nullptr;
std::random_device rd;
std::uniform_int_distribution<int> dis(1, 100);
std::mt19937 gen(rd());
while (--len >= 0) {
auto *temp = new ListNode(dis(gen), p);
p = temp;
}
return p;
}
#endif //LEECODE_C_LISTS_H

View File

@@ -0,0 +1,128 @@
#include <stdio.h>
#include <stdbool.h>
#define MAX_SIZE 100
typedef enum { INT_TYPE, FLOAT_TYPE, DOUBLE_TYPE } ElementType;
typedef struct {
ElementType type;
union {
int intValue;
float floatValue;
double doubleValue;
} data;
} Item;
typedef struct {
Item items[MAX_SIZE];
int size;
} PriorityQueue;
PriorityQueue createPriorityQueue() {
PriorityQueue pq;
pq.size = 0;
return pq;
}
bool isLess(Item item1, Item item2) {
if (item1.type != item2.type) {
fprintf(stderr, "错误:无法比较不同类型的元素。\n");
return false;
}
switch (item1.type) {
case INT_TYPE:
return item1.data.intValue < item2.data.intValue;
case FLOAT_TYPE:
return item1.data.floatValue < item2.data.floatValue;
case DOUBLE_TYPE:
return item1.data.doubleValue < item2.data.doubleValue;
default:
fprintf(stderr, "错误:未知的元素类型。\n");
return false;
}
}
void swap(Item* item1, Item* item2) {
Item temp = *item1;
*item1 = *item2;
*item2 = temp;
}
void push(PriorityQueue* pq, Item newItem) {
if (pq->size >= MAX_SIZE) {
fprintf(stderr, "错误:优先队列已满,无法插入元素。\n");
return;
}
int childIndex = pq->size;
pq->items[childIndex] = newItem;
pq->size++;
int parentIndex = (childIndex - 1) / 2;
while (childIndex > 0 && isLess(pq->items[childIndex], pq->items[parentIndex])) {
swap(&pq->items[childIndex], &pq->items[parentIndex]);
childIndex = parentIndex;
parentIndex = (childIndex - 1) / 2;
}
}
Item pop(PriorityQueue* pq) {
if (pq->size <= 0) {
fprintf(stderr, "错误:优先队列为空,无法弹出元素。\n");
Item emptyItem;
emptyItem.type = INT_TYPE; // 返回一个空元素
emptyItem.data.intValue = 0;
return emptyItem;
}
Item minItem = pq->items[0];
pq->size--;
pq->items[0] = pq->items[pq->size];
int parentIndex = 0;
while (true) {
int leftChildIndex = parentIndex * 2 + 1;
int rightChildIndex = parentIndex * 2 + 2;
int smallestIndex = parentIndex;
if (leftChildIndex < pq->size && isLess(pq->items[leftChildIndex], pq->items[smallestIndex])) {
smallestIndex = leftChildIndex;
}
if (rightChildIndex < pq->size && isLess(pq->items[rightChildIndex], pq->items[smallestIndex])) {
smallestIndex = rightChildIndex;
}
if (smallestIndex == parentIndex) {
break; // 已经是最小堆,无需继续下沉
}
swap(&pq->items[parentIndex], &pq->items[smallestIndex]);
parentIndex = smallestIndex;
}
return minItem;
}
int main() {
PriorityQueue pq = createPriorityQueue();
// 向优先队列中插入一些元素
Item item1, item2, item3;
item1.type = INT_TYPE;
item1.data.intValue = 5;
item2.type = INT_TYPE;
item2.data.intValue = 2;
item3.type = INT_TYPE;
item3.data.intValue = 10;
push(&pq, item1);
push(&pq, item2);
push(&pq, item3);
// 从优先队列中弹出元素
Item minItem = pop(&pq);
printf("弹出的最小元素为:%d\n", minItem.data.intValue);
return 0;
}

View File

@@ -0,0 +1,15 @@
# QUEUE
## PriorityQueue - 优先队列
- 优先队列也是一种队列只不过不同的是优先队列的出队顺序是按照优先级来的可能需要找到元素集合中的最小或者最大元素可以利用优先队列ADT来完成操作优先队列ADT是一种数据结构它支持插入和删除最小值操作返回并删除最小元素或删除最大值操作返回并删除最大元素
- 这些操作等价于队列的`enQueue``deQueue`操作,区别在于,对于优先队列,元素进入队列的顺序可能与其被操作的顺序不同,作业调度是优先队列的一个应用实例,它根据优先级的高低而不是先到先服务的方式来进行调度;
- 如果最小键值元素拥有最高的优先级,那么这种优先队列叫作**升序优先队列**(即总是先删除最小的元素),类似的,如果最大键值元素拥有最高的优先级,那么这种优先队列叫作**降序优先队列**(即总是先删除最大的元素);由于这两种类型时对称的,所以只需要关注其中一种,如升序优先队列;
- 优先队列的应用
- 数据压缩:赫夫曼编码算法;
- 最短路径算法Dijkstra算法
- 最小生成树算法Prim算法
- 事件驱动仿真:顾客排队算法;
- 选择问题查找第k个最小元素
- 等等等等....

66
dataStruct/Tree/Tree.h Normal file
View File

@@ -0,0 +1,66 @@
//
// Created by 李洋 on 2023/8/14.
//
#ifndef LEECODE_C_TREE_H
#define LEECODE_C_TREE_H
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
#include <iostream>
#include <random>
#include <queue>
TreeNode *creatRandomTree(int size) {
if (size == 0) {
return nullptr;
}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(1, 100);
std::queue<int> Q;
std::queue<TreeNode *> T;
for (int i = size; i > 0; --i) {
Q.push(dis(gen));
std::cout << Q.back() << " ";
}
std::cout << std::endl;
TreeNode *head = new TreeNode(Q.front());
T.push(head);
Q.pop();
while (!Q.empty()) {
if (T.front()->left != nullptr && T.front()->right != nullptr) {
T.pop();
}
TreeNode *temp = new TreeNode(Q.front());
Q.pop();
if (T.front()->left == nullptr) {
T.front()->left = temp;
T.push(temp);
continue;
}
if (T.front()->right == nullptr) {
T.front()->right = temp;
T.push(temp);
}
}
return head;
}
#endif //LEECODE_C_TREE_H

View File

@@ -0,0 +1,56 @@
//
// Created by 李洋 on 2023/9/6.
//
#ifndef LEECODE_C_TREESTACK_H
#define LEECODE_C_TREESTACK_H
#pragma once
#include <iostream>
#include <vector>
#include "./Tree.h"
class TreeStack {
private:
std::vector<TreeNode *> data;
public:
// 入栈操作
void push(TreeNode *value) {
data.push_back(value);
}
// 出栈操作
TreeNode *pop() {
if (!isEmpty()) {
TreeNode *topValue = data.back();
data.pop_back();
return topValue;
} else {
std::cerr << "Error: Stack is empty." << std::endl;
return nullptr; // 可以根据需要返回其他值或抛出异常
}
}
// 获取栈顶元素
TreeNode *top() const {
if (!isEmpty()) {
return data.back();
} else {
std::cerr << "Error: Stack is empty." << std::endl;
return nullptr; // 可以根据需要返回其他值或抛出异常
}
}
// 检查栈是否为空
bool isEmpty() const {
return data.empty();
}
// 获取栈的大小
size_t size() const {
return data.size();
}
};
#endif //LEECODE_C_TREESTACK_H