寒假学习总结
整个寒假都走在数据结构与算法的路上,深入学习了其中多个板块,刷了一些与之对应的题目,下面来一期总结(c)
(emmm,主播在寒假试着去学习了几大语言的语法基础(丢丢) 如Java c++ python,从中感受自己真正热爱的语言是谁,已经确定好岗位与语言,408 语言基础以及岗位技术栈的学习会提上日程)
一.搜索算法:深度优先搜索(DFS)与广度优先搜索(BFS)是图和树遍历的基本算法。
DFS常用于找寻所有可能解,BFS常用于求最短路径
- 迷宫问题:在求解迷宫中从起点到终点的路径问题时,DFS 和 BFS 都可使用。DFS 会沿着一条路径一直深入探索,直到无法继续或找到终点,若走错则回退尝试其他路径,优点是代码实现相对简单,递归性强,能快速找到一条可行路径,但可能不是最短路径;BFS 从起点开始逐层向外扩展,先访问距离起点近的点,因此当找到终点时,走过的路径就是最短路径,缺点是需要维护队列来存储待访问的节点,空间复杂度相对较高。
- 图的遍历:对于给定的图,要求遍历图中所有节点。比如在社交网络关系图中,要访问所有用户节点。DFS 从一个起始节点开始,递归访问其邻接节点,能快速深入探索图的结构,适合对图的连通性判断等;BFS 则从起始节点开始,逐层访问其邻居节点,可用于计算节点间的最短距离或寻找最小步数问题。
- 连通分量查找:在一个无向图中,需要找出所有的连通分量。DFS 可以从图中任意一个未访问的节点出发,递归地访问其所有连通的节点,标记已访问的节点,直到所有节点都被访问过,每一次从新的未访问节点开始的 DFS 过程都能找到一个新的连通分量;BFS 同样从一个未访问节点开始,使用队列逐层扩展访问其邻居节点,当队列为空时,一个连通分量查找完成,重复此过程直到所有节点被访问。
- 棋盘问题:在棋盘上的棋子移动问题,如八皇后问题、马走日等。以马走日为例,DFS 可以通过递归尝试马的每一种可能走法,直到找到目标位置或遍历完所有可能,能快速探索各种走法组合;BFS 则按照马的走法规则,从起始位置开始逐层扩展,记录每个位置的步数,当找到目标位置时,记录的步数就是最少步数。
两种算法在题目中各具优势 各具缺点。
ok,讲完两种搜索算法,来看它们具体实现,DFS通常使用栈实现而与之对应的BFS则由队列实现,所以现在来到数据结构的版块
二.数据结构:栈,队列,散列表(哈希表),二叉树。(c语言无具体函数,手动实现)
栈:栈是一种后进先出的数据结构,只允许在一端进行操作(入栈,出栈)
- 栈的应用
- 括号匹配问题:例如判断一个字符串中的括号(如圆括号、方括号、花括号)是否匹配。可以使用栈来解决,遍历字符串,遇到左括号时将其压入栈中,遇到右括号时检查栈顶元素是否为对应的左括号,如果是则将栈顶元素弹出,否则括号不匹配。遍历结束后,如果栈为空,则说明括号完全匹配,否则不匹配。比如对于字符串 “([{}])”,就可以通过栈来判断其括号是匹配的。
- 表达式求值:在计算中缀表达式(如 “3 + ( 4 * 2 - 1)”)的值时,可以使用两个栈,一个用于存储操作数,一个用于存储操作符。遍历表达式,遇到操作数就压入操作数栈,遇到操作符时,根据操作符的优先级与栈顶操作符比较,若当前操作符优先级低或相等,则从操作数栈中弹出两个操作数,从操作符栈中弹出一个操作符进行计算,并将结果压入操作数栈,重复此过程直到遍历结束。最后操作数栈中剩下的元素就是表达式的值。
- 函数调用和递归模拟:在一些需要模拟函数调用过程或递归过程的题目中,可以使用栈来记录函数调用的参数、局部变量等上下文信息。例如在实现一个简单的递归算法的非递归版本时,通过栈来保存需要回溯的状态。
栈的基本功能代码实现
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义栈的结构体
typedef struct Stack {int top;int data[MAX_SIZE];
} Stack;// 初始化栈
void initStack(Stack *s) {s->top = -1;
}// 判断栈是否为空
int isEmpty(Stack *s) {return s->top == -1;
}// 判断栈是否已满
int isFull(Stack *s) {return s->top == MAX_SIZE - 1;
}// 入栈操作
void push(Stack *s, int value) {if (isFull(s)) {printf("Stack is full!\n");return;}s->data[++(s->top)] = value;
}// 出栈操作
int pop(Stack *s) {if (isEmpty(s)) {printf("Stack is empty!\n");return -1;}return s->data[(s->top)--];
}// 获取栈顶元素
int peek(Stack *s) {if (isEmpty(s)) {printf("Stack is empty!\n");return -1;}return s->data[s->top];
}
队列:队列是一种先进先出的数据结构,允许在头部出队列,尾部入队列
- 队列的应用
- 广度优先搜索(BFS):在图或树的遍历中,BFS 算法使用队列来存储待访问的节点。从起始节点开始,将其加入队列,然后不断从队列中取出节点,访问该节点,并将其未访问的邻居节点加入队列,直到队列为空。例如在迷宫问题中,求从起点到终点的最短路径,可以使用 BFS 结合队列来实现。
- 任务调度:假设有一个多任务处理系统,任务按照到达的顺序依次进入队列,系统从队列头部取出任务进行处理,这就是典型的队列应用。比如打印机的任务队列,打印任务按照提交的先后顺序依次打印。
- 滑动窗口问题:在一些数组相关的题目中,如求滑动窗口内的最大值或最小值,可以使用队列(双端队列)来实现。通过维护队列中元素的顺序,使其满足窗口内元素的相关要求,从而高效地解决问题。例如,对于数组 [1, 3, -1, -3, 5, 3, 6, 7],窗口大小为 3,使用双端队列可以在 O (n) 的时间复杂度内求出每个窗口内的最大值。
队列基本功能代码实现
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义队列的结构体
typedef struct Queue {int front;int rear;int data[MAX_SIZE];
} Queue;// 初始化队列
void initQueue(Queue *q) {q->front = q->rear = -1;
}// 判断队列是否为空
int isQueueEmpty(Queue *q) {return q->front == -1;
}// 判断队列是否已满
int isQueueFull(Queue *q) {return (q->rear + 1) % MAX_SIZE == q->front;
}// 入队操作
void enqueue(Queue *q, int value) {if (isQueueFull(q)) {printf("Queue is full!\n");return;}if (q->front == -1) {q->front = q->rear = 0;} else {q->rear = (q->rear + 1) % MAX_SIZE;}q->data[q->rear] = value;
}// 出队操作
int dequeue(Queue *q) {if (isQueueEmpty(q)) {printf("Queue is empty!\n");return -1;}int value = q->data[q->front];if (q->front == q->rear) {q->front = q->rear = -1;} else {q->front = (q->front + 1) % MAX_SIZE;}return value;
}// 获取队头元素
int frontElement(Queue *q) {if (isQueueEmpty(q)) {printf("Queue is empty!\n");return -1;}return q->data[q->front];
}
散列表:又称哈希表,是根据键(key)直接访问值(value)的数据结构,通过一个哈希函数将键映射到表中一个位置来访问记录,时间复杂度能达到o(1)
最简单的一个哈希函数 hash(key)=key,那么如果由两个键生成到同一个哈希值,这时就会产生哈希冲突,通常办法为取模运算hash(key)=key%(table_size),还会使用线性探测减少哈希冲突,还有更多更好减少哈希冲突的方法,由于主播没学,就不过多讲解
下面是哈希表基础功能的实现
KeyValue hashTable[HASH_SIZE];// 简单的哈希函数
unsigned int hash(int key1, int key2)
{return ((unsigned long long)key1 * 1000000007 + key2) % HASH_SIZE;
}// 插入或更新键值对
void insert(int key1, int key2, int value)
{unsigned int index = hash(key1, key2);// 线性探测解决哈希冲突while (hashTable[index].isOccupied && (hashTable[index].key1 != key1 || hashTable[index].key2 != key2)){index = (index + 1) % HASH_SIZE;}// 若该位置未被占用,标记为已占用if (!hashTable[index].isOccupied){hashTable[index].isOccupied = 1;hashTable[index].key1 = key1;hashTable[index].key2 = key2;}// 更新值hashTable[index].value = value;
}// 根据键查找值
int find(int key1, int key2)
{unsigned int index = hash(key1, key2);unsigned int start = index;// 线性探测查找键值对while (hashTable[index].isOccupied) {if (hashTable[index].key1 == key1 && hashTable[index].key2 == key2){return hashTable[index].value;}index = (index + 1) % HASH_SIZE;// 若回到起始位置,说明未找到if (index == start){break;}}return 0;
}
二叉树 :二叉树是一种树形数据结构,每个节点最多有两个子节点,通常被称作左子节点和右子节点。
二叉树遍历方式有
先序遍历:
// 前序遍历
void preOrder(TreeNode* root) {if (root != NULL) {printf("%d ", root->data);preOrder(root->left);preOrder(root->right);}
}
中序遍历:
// 中序遍历
void inOrder(TreeNode* root) {if (root != NULL) {inOrder(root->left);printf("%d ", root->data);inOrder(root->right);}
}
后序遍历:
// 后序遍历
void postOrder(TreeNode* root) {if (root != NULL) {postOrder(root->left);postOrder(root->right);printf("%d ", root->data);}
}
emmmm,还有已知中序与二之一求另一,看主播以前的文章
三.算法思想:DP 二分 并查集
1.动态规划是一种通过把原问题分解为相对简单的子问题,并保存子问题的解来避免重复计算,从而解决复杂问题的算法策略。它通常适用于具有重叠子问题和最优子结构性质的问题。
2.二分查找是一种在有序数组中查找特定元素的高效算法。它通过将数组分成两部分,每次比较中间元素与目标元素的大小,然后根据比较结果缩小查找范围,直到找到目标元素或确定目标元素不存在。时间复杂度为O(log n)
3.并查集是一种用于处理不相交集合的合并与查询问题的数据结构。它支持两种主要操作:
- 合并(Union):将两个不相交的集合合并为一个集合。
- 查找(Find):确定一个元素所属的集合。
四。图论算法
最小生成树算法:prime与kruskal(主播只学过kruskal)
实现步骤
将图中的所有边按照权值从小到大进行排序:可以使用快速排序、归并排序等排序算法,将边按照权值升序排列。
- 初始化一个空的边集合作为最小生成树:这个集合初始时不包含任何边。
- 依次遍历排序后的边:对于每条边,如果将其加入到当前的边集合中不会形成环,则将该边加入到边集合中;否则,跳过这条边。
- 重复步骤 3:直到边集合中的边数等于顶点数减 1,此时边集合构成的就是图的最小生成树。
kruskal的简单实现
#include <stdio.h>#define MAX_VERTICES 100
#define MAX_EDGES 100// 定义边的结构体
typedef struct {int src, dest, weight;
} Edge;// 定义图的结构体
typedef struct {int V, E;Edge edges[MAX_EDGES];
} Graph;// 比较函数,用于 qsort 按边的权值从小到大排序
int compare(const void *a, const void *b) {Edge *edge1 = (Edge *)a;Edge *edge2 = (Edge *)b;return edge1->weight - edge2->weight;
}// 查找元素所在的集合
int find(int parent[], int i) {while (parent[i] != i) {i = parent[i];}return i;
}// 合并两个集合
void unionSets(int parent[], int x, int y) {int xroot = find(parent, x);int yroot = find(parent, y);parent[xroot] = yroot;
}// Kruskal 算法实现
void kruskalMST(Graph *graph) {int V = graph->V;Edge result[MAX_VERTICES - 1]; // 存储最小生成树的边int e = 0; // 最小生成树的边数int i = 0; // 当前遍历的边的索引// 按边的权值从小到大排序qsort(graph->edges, graph->E, sizeof(Edge), compare);// 为每个顶点分配一个集合int parent[MAX_VERTICES];for (int v = 0; v < V; ++v) {parent[v] = v;}// 遍历排序后的边while (e < V - 1 && i < graph->E) {Edge next_edge = graph->edges[i++];int x = find(parent, next_edge.src);int y = find(parent, next_edge.dest);// 如果加入这条边不会形成环,则加入最小生成树if (x != y) {result[e++] = next_edge;unionSets(parent, x, y);}}// 输出最小生成树的边printf("最小生成树的边集合:\n");int total_weight = 0;for (i = 0; i < e; ++i) {printf("(%d - %d) 权值: %d\n", result[i].src, result[i].dest, result[i].weight);total_weight += result[i].weight;}printf("最小生成树的总权值: %d\n", total_weight);
}int main() {Graph graph;graph.V = 4; // 顶点数graph.E = 5; // 边数// 添加边graph.edges[0].src = 0;graph.edges[0].dest = 1;graph.edges[0].weight = 10;graph.edges[1].src = 0;graph.edges[1].dest = 2;graph.edges[1].weight = 6;graph.edges[2].src = 0;graph.edges[2].dest = 3;graph.edges[2].weight = 5;graph.edges[3].src = 1;graph.edges[3].dest = 3;graph.edges[3].weight = 15;graph.edges[4].src = 2;graph.edges[4].dest = 3;graph.edges[4].weight = 4;// 调用 Kruskal 算法kruskalMST(&graph);return 0;
}
这个寒假的学习让我在数据结构与算法领域取得了显著进步。理论与实践结合,提升了我的问题解决能力和编程技巧。未来,我将继续深入学习高级算法和数据结构,如线段树、树状数组等,并参与更多算法竞赛,提升自己的算法水平。相信这段学习经历会为我今后的学习和工作打下坚实的基础,激励我在计算机科学领域不断探索前行。
相关文章:
寒假学习总结
整个寒假都走在数据结构与算法的路上,深入学习了其中多个板块,刷了一些与之对应的题目,下面来一期总结(c) (emmm,主播在寒假试着去学习了几大语言的语法基础(丢丢) 如Ja…...

Java Web开发实战与项目——用户认证与授权模块开发
Web应用中,用户认证与授权是至关重要的功能,确保只有合法用户才能访问受保护的资源。Spring Security作为一个强大的安全框架,支持多种认证与授权方式。在本章节中,我们将深入探讨三种常见的用户认证与授权方案:基于To…...

力扣每日一题【算法学习day.129】
前言 ###我做这类文章一个重要的目的还是记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!! 习题 1.数组列表中的最大距离 题目链接…...

uni-app发起网络请求的三种方式
uni.request(OBJECT) 发起网络请求 具体参数可查看官方文档uni-app data:请求的参数; header:设置请求的 header,header 中不能设置 Referer; method:请求方法; timeout:超时时间,单位 ms&a…...

字节火山云DeepSeek接入教程,支持联网,速度超快。
大家好,我是苍何。 在使用 DeepSeek 官网,实在是卡的我差点学猪叫,于是我一直在寻找替代方案。 要求就 2:满血,速度快。(当然能联网更好)。 我也一度使用了如硅基流动 API,发现也开…...
C语言指针学习笔记
1. 指针的定义 指针(Pointer)是存储变量地址的变量。在C语言中,指针是一种非常重要的数据类型,通过指针可以直接访问和操作内存。 2. 指针的声明与初始化 2.1 指针声明 指针变量的声明格式为:数据类型 *指针变量名…...
FreeRTOS-rust 编译分析
目录介绍 FreeRTOS-rust ├── .cargo # 对 cargo 本身的配置 │ └── config.toml ├── Cargo.toml # 对当前工作空间的配置 ├── freertos-cargo-build # 负责对 freertos 源码进行编译 │ ├── Cargo.toml # 对当前 package 进行配置 │ └…...

【解决方法】vite-plugin-svg-icons使用中出现问题[vite] Cannot find package ‘fast-glob‘
问题长这样: 参考文章:https://medium.com/wumeng9028/vite-plugin-svg-icons-error-cannot-find-package-fast-glob-8cb03d19c0ac 解决方法:pnpm add fast-glob -D package.json {"vite-plugin-svg-icons": "2.0.1"…...

[Qt] 使用QUndoStack运行到cmd->isObsolete()崩溃
redo/undo中又push了 崩溃情况崩溃原因解决方法 崩溃情况 在正常调用QUndoStack的redo/undo时,崩溃在了这里 unknown:0 QWidget: Cannot create a QWidget without QApplication. 崩溃原因 在正常调用QUndoStack的redo/undo时,因为自身的逻辑处理&a…...

大白话实战Sentinel
Sentinel是SpringCloudAlibaba提供的用来做服务保护的框架,而服务保护的常见手段就是限流和熔断降级。在大型分布式系统里面,由于微服务众多,所以服务之间的稳定性需要做特别关注,Sentinel的核心包就提供了从多个维度去保护服务稳定的策略,而且这些保护策略都可以连接上Se…...

DL/CV领域常见指标术语(FLOPS/mIoU/混淆矩阵/F1-measure)------一篇入门
1. FLOPS、FLOPs和GFLOPs FLOPS: floating-point operations per second,每秒浮点运算次数,用来衡量硬件性能。 FLOPs:floating point of operations,是浮点运算次数,用来衡量算法、模型的复杂度。 GFLOPSÿ…...

SprutCAMX16数控软件介绍
SprutCAM X 16 是一款功能强大的CAM(计算机辅助制造)软件,专为数控机床编程和制造过程优化设计。它广泛应用于机械加工、模具制造、3D打印等领域,支持多轴加工、车铣复合、机器人加工等多种加工方式。以下是SprutCAM X 16的主要特…...

Miniconda + VSCode 的Python环境搭建
目录: 安装 VScode 安装 miniconda 在VScode 使用conda虚拟环境 运行Python程序 1.安装 vscode 编辑器 官网链接:Visual Studio Code - Code Editing. Redefined 下载得到:,双击安装。 安装成功…...
TRELLIS 部署笔记
目录 依赖项安装 kaolin安装: 安装和运行报错解决 u2net.onnx 下载 解决方法,就是自行下载,然后拷贝到目录/root/.u2net bash测试u2net: 报错GaussianRasterizationSettings.__new__() got an unexpected keyword argument…...

深入解析Qt事件循环
在Qt开发中,QApplication::exec()这行代码是每个开发者都熟悉的“魔法咒语”。为什么GUI程序必须调用它才能响应操作?为何耗时操作会导致界面冻结?本文将以事件循环为核心,揭示Qt高效运转的底层逻辑,探讨其设计哲学与最…...

Visual Studio Code 集成 Baidu Comate
文章目录 安装Baidu Comate插件 安装Baidu Comate插件 从左主侧栏中 点击 【扩展】这个图标,然后在上方输入栏中输入 baidu comate —>选中列出的Bai Comate —>点击 【安装】按钮,等待安装完毕…...

「正版软件」PDF Reader - 专业 PDF 编辑阅读工具软件
PDF Reader 轻松查看、编辑、批注、转换、数字签名和管理 PDF 文件,以提高工作效率并充分利用 PDF 文档。 像专业人士一样编辑 PDF 编辑 PDF 文本 轻松添加、删除或修改 PDF 文档中的原始文本以更正错误。自定义文本属性,如颜色、字体大小、样式和粗细。…...
Kafka消息服务之Java工具类
注:此内容是本人在另一个技术平台发布的历史文章,转载发布到CSDN; Apache Kafka是一个开源分布式事件流平台,也是当前系统开发中流行的高性能消息队列服务,数千家公司使用它来实现高性能数据管道、流分析、数据集成和关…...
迪威模型网:免费畅享 3D 打印盛宴,科技魅力与趣味创意并存
还在为寻找优质3D打印模型而发愁?快来迪威模型网(https://www.3dwhere.com/),一个集前沿科技与无限趣味于一体的免费3D打印宝藏平台! 踏入迪威模型网,仿佛开启一场未来科技之旅。其“3D打印”专区ÿ…...
ECharts极简入门
ECharts 是一个基于 JavaScript的开源可视化图表库,广泛应用于数据可视化的场景中,支持多种图表类型,如柱状图、折线图、饼图、散点图、雷达图等,且具有强大的自定义功能。 1. ECharts 基本使用 首先需要引入 ECharts 库…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...