- 博客(45)
- 收藏
- 关注
原创 Linux项目自动化构建工具————make/makefile
1.make:2.makefile:一个文本文件(命名为 或 ),定义项目编译规则和依赖关系。 示例解释: 是目标文件,依赖 。执行 时,自动调用 编译生成 。三、清理操作(clean 规则)1. 添加清理规则为什么 后面没有依赖文件?因为 是伪目标,不依赖任何文件,直接执行命令。 2. 伪目标的作用 伪目标:不生成实际文件,仅执行命令。 的作用:强制 执行该规则,即使存在名为 的文件。依赖关系:目标文件是否需要重新生成,取决于依赖文件是否更
2025-04-09 15:06:52
322
原创 哈希表(哈希桶版本)
由数组和多个桶构成。数组元素对应桶,桶可以是链表、二叉树等(这篇文章主要讲解链表版本的)。插入时,哈希函数算哈希值,按值找数组位置放元素;查找、删除同理,再按桶对应数据结构规则操作。:哈希函数模板(默认支持整型和string特化):键类型(必须可哈希)
2025-03-27 13:45:29
896
原创 哈希表(除留余数法)
a ≥ 0.7EXIST:该位置有有效数据EMPTY:该位置为空DELETE:该位置数据被删除解决冲突探测时无法区分“从未插入”和“已删除”的问题删除时不物理删除数据,仅标记状态,避免破坏探测链:整数类型(intchar等):无法直接处理字符串等复杂类型:通过乘法和累加减少哈希冲突:字符串需要特殊处理,避免str[0]直接取首字符导致高冲突率。
2025-03-15 15:25:35
576
原创 C++----红黑树&&map和set的封装
/ map侧迭代器定义// set侧迭代器定义关键差异容器迭代器类型可修改性map普通迭代器可修改value,不可修改keysetconst迭代器完全不可修改元素。
2025-03-08 19:14:32
1121
原创 数据结构--AVL树
AVL 树是一种自平衡的二叉搜索树。它在向二叉搜索树中插入新节点时,通过特定的旋转操作,保证每个节点的左右子树高度之差的绝对值不超过 1。这使得 AVL 树在动态插入和删除节点过程中,始终保持较为平衡的状态,从而保证基本操作的时间复杂度稳定在 O (log n)。
2025-03-08 19:12:52
1101
原创 linux工具
(Package)是预先编译好的应用程序及其依赖项的集合,类似于 Windows 中的安装程序(如.exe文件)。在 Linux 中,软件包包含:可执行程序配置文件依赖关系信息安装脚本gccmake.rpm。
2025-03-04 23:56:12
942
原创 C++----异常
在服务器开发中,为了更好地管理和处理不同类型的异常,通常会设计一个异常继承体系。// 异常基类(抽象错误类型)// Exception 类:作为基类异常,包含异常信息 _errmsg 和异常编号 _id,// 并定义了虚函数 what() 用于返回异常信息,支持多态。public:// 虚析构保证正确释放protected:// 错误描述int _id;// 错误编号// SQL操作异常(具体错误类型)
2025-03-04 23:55:14
1071
原创 C++----set和map
vector、list、deque、forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。
2025-02-22 11:38:17
916
原创 二叉搜索树
二叉搜索树是一种二叉树,对于树中的每个节点,其左子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值。这种特性使得二叉搜索树在查找、插入和删除操作上具有较高的效率,平均时间复杂度为O(logn) ,但在最坏情况下(树退化为链表)时间复杂度为O(n)。
2025-02-18 09:03:50
741
原创 C++----多态
纯虚函数的作用:在抽象类中定义纯虚函数,间接强制派生类重写该虚函数。派生类若不重写纯虚函数,自身也会成为抽象类,同样不能实例化对象。抽象类的使用:虽然抽象类不能实例化对象,但可以定义指向抽象类的指针或引用,通过这些指针或引用调用派生类重写后的虚函数,实现多态行为。在上述代码中, Func 函数通过 Car* 指针调用不同派生类的 Drive 函数,体现了这一特性。
2025-02-14 13:35:26
728
原创 C++----STL(vector)
如果已经掌握string用法的,理解vector会更容易。vector中的find:vector不像string在成员函数中直接提供了find(),而是通过<algorithm>头文件中的find函数,用于查找元素的位置。原因:vector在insert或erase操作后,可能会重新分配内存(尤其是当容量不足时),导致所有指向该vector的迭代器失效。在实际中非常的重要,在实际中我们熟悉常见的接口就可以,下面列出了。中的元素,因为这样做会导致未定义行为。在C++的STL(标准模板库)中,
2025-01-22 23:38:48
870
原创 C++----STL(string)
迭代器(iterator)是一种类似指针的对象,用于访问容器中的元素。它可能是一个指针,也可能是一个封装了指针行为的对象。迭代器提供了对容器元素的顺序访问,可以遍历容器中的元素。
2025-01-13 21:47:37
970
原创 C++----模板初阶
注意:普通类的类名和类型是一样的,类模板的类名和类型却不一样。// 类模板// 类名:Stack// 类型:Stack<T>public:// 其他方法...~Stack()_size = 0;int _size;_size = 0;_size++;
2024-12-27 10:43:25
995
原创 C/C++内存管理
和new/delete的区别malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。malloc和free是函数,new和delete是操作符malloc申请的空间不会初始化,new可以初始化malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型。
2024-12-25 17:38:05
1515
原创 C++----类与对象(下篇)
内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。注意内部类就是外部类的友元类(参见友元类的定义),内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元,不可以直接访问内部类的私有属性的成员。特性1.内部类可以定义在外部类的publicprotectedprivate。2.注意内部类可以直接访问外部类中的static成员,不需要外部类的对象类名。
2024-12-23 13:24:50
1216
原创 C++----类与对象(上篇)
/类体:由成员函数和成员变量组成//一定要有后面的分号class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。在这种方式中,类的声明和成员函数的定义都放在类体中。当成员函数在类体中定义时,编译器通常会将其视为内联函数。内联函数在编译时会被展开,以减少函数调用的开销。但请注意,如果成员函数较为复杂或体积较大,编译器可能会忽略内联请求。
2024-12-14 09:12:43
1428
原创 C++----入门篇
命名空间通过namespace关键字来定义,可以包含变量、函数、类型等。// 定义一个命名空间lynnint a = 10;// 全局域中的aint a = 20;// 访问全局域的a// 访问命名空间bit中的a// 调用全局域的printA函数::printA();// 调用命名空间lynn中的printA函数return 0;在C++中,函数的声明和定义通常分开进行,特别是在使用头文件(.h)和源文件(.cpp)的情况下。
2024-12-12 10:01:10
1148
原创 排序----归并排序
归并排序是一种有效的排序算法,它采用分治策略来排序数据。其基本思想是分解和合并,分解就是将待排序数组分成两半,递归地对这两半进行归并排序;合并就是将两个已经排好序的子数组合并称一个有序数组。这里会讲到递归版本的归并排序和非递归版本的归并排序。
2024-12-10 13:04:47
1224
原创 交换排序----快速排序
③right向左移动时找到了小于或等于key的值,left向右移动占到了大于或等于key的值,left和right位置上的值交换,然后right继续向左移动找小于或等于key的值,但是right已经找不到小于或等于key的值了,那它就会与left相遇,此时left上的值是刚刚从right位置上交换过来的小于或等于key的值,所以他们还是在小于或等于key上的值相遇。其实在递归版本的快速排序中,每一次递归中变化的主要是区间的大小,所以我们可以在每次单趟排序完后,让对应区间的子区间入栈。
2024-12-06 15:44:44
1213
原创 插入排序⁻⁻⁻⁻直接插入排序&希尔排序
直接插入排序其实是一种很简单的排序算法哦。它就像我们平时整理扑克牌一样,一张一张地来,把每一张牌都插到已经排好序的部分里面,直到全部都排好。希尔排序,又称为缩小增量排序,是直接插入排序的一种更高效的改进版本。前面我们知道,直接插入排序比最差的条件下时间复杂度可以达到O(n²),但是在部分有序的情况下,它的性能还是不错的。希尔排序的基本思想是预排序,即先将数组内的数据变得部分有序,最后再通过直接插入排序将部分有序的数组进组排序。那它具体是如何实现预排序的呢?接下来我们会进行讲解。
2024-12-03 15:37:33
984
原创 分治的思想(力扣965、力扣144、牛客KY11)
分治思想是将问题分解为更小子问题,分别解决后再合并结果。二叉树中常用此思想,因其结构递归,易分解为左右子树问题,递归解决后合并结果。这篇文章会讲解用分治的思想去解决二叉树的一些题目,顺便会强调在做二叉树的题过程中我容易出错的地方。
2024-12-02 13:08:51
1211
原创 链式二叉树
在探讨数据结构时,我们不难发现,虽然普通的链式二叉树在存储数据上可能不如前面用数组模拟二叉树直观,但其独特的结构为后续的复杂数据结构奠定了基础。特别是当我们谈及搜索问题时,搜索二叉树以其高效的搜索性能脱颖而出,与二分查找法有着异曲同工之妙。但是,二分查找法在实际应用中受限颇多,它要求数据必须有序且存储在数组中,这一条件往往难以满足。更何况,数组在增删元素时,需要移动大量数据,效率较低。
2024-12-01 11:37:22
1370
原创 TopK算法
TopK主要解决的是从一组数据中选择出前K个最大或最小的元素的问题。在计算机科学和数据分析领域,TopK方法被广泛应用于排序、搜索和排名等任务,它对于处理海量数据特别有效。
2024-11-29 09:52:40
720
原创 数据结构--树&二叉树&顺序结构存储的二叉树(堆)
1.检查并扩容(如需):若堆满,则扩容。2.末尾插入:将新元素添加到堆数组的末尾。3.向上调整:从新元素开始,与其父节点比较。若新元素大,则交换位置,并继续向上比较直至不需交换或到达根节点。4.更新大小:堆大小加1。1.检查非空:若堆为空,则直接返回。2.交换并减小:将堆顶与末尾元素交换,然后减小堆大小。3.向下调整:从新的堆顶开始,与其孩子比较并交换(如需),直至堆性质恢复或到达堆底。
2024-11-27 08:07:02
1513
原创 数据结构--循环队列&力扣622题
在实现循环队列时,确实有很多常见的陷阱和容易犯的错误。1.明确队列的“满”和“空”条件循环队列通常有两种实现方式:基于“满”条件的和基于“空”条件的。在基于“满”条件的实现中,tail 指向下一个要插入元素的位置,而在基于“空”条件的实现中,则 tail 和front相等。清楚地区分这两种情况,并确保您的所有操作(如插入、删除、检查队列是否为空或满)都基于您选择的条件。2.正确处理数组索引和循环当 tail 或front索引达到数组的末尾或数组的头时,要正确处理他们循环后的位置。
2024-11-23 14:30:49
1266
原创 数据结构--栈和队列
回顾前面链表的测试案例,我们定义的是链表节点指针;在栈的测试案例中,我们定义的是结构体,并没有使用指针。这是为什么呢?选择使用结构体本身还是结构体指针通常取决于该数据结构的设计需求和使用场景。下面我们将从栈和链表的数据结构、操作和存储方式来分析为什么上面的代码中,栈使用了结构体本身,而链表使用了结构体指针。我们先来看栈:栈通常被设计为在固定大小的数组中存储元素,或者在某些实现中,它可能动态地调整其大小(上面则是通过分配更大的数组并复制旧数据)。
2024-11-22 15:04:08
1404
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人