
数据结构
Michael_Good
脚踏实地,不负时光!
展开
-
【Linux】container_of 的使用心得。
总结下container_of的原理。原创 2025-01-11 14:39:07 · 138 阅读 · 0 评论 -
【C/C++】Protobuf与nlohmann/json的比较
特性Protobufnlohmann/json数据格式二进制格式,紧凑,不可读文本格式,可读性强性能序列化/反序列化速度快,内存占用小序列化/反序列化速度慢,内存占用大跨语言支持多语言支持,代码生成广泛的语言支持,无需代码生成学习曲线学习成本高,文档丰富学习成本低,API简洁易用扩展性和灵活性强类型系统,字段编号,向后兼容性好弱类型系统,动态性高,灵活性好生态系统成熟的生态系统,官方支持,gRPC等轻量级库,社区活跃,单头文件集成原创 2025-01-06 14:20:21 · 316 阅读 · 0 评论 -
QtCreator中使用MSVC2017-x64编译器出现Error: lnk1257 代码生成失败
【代码】QtCreator中使用MSVC2017-x64编译器出现Error: lnk1257 代码生成失败。原创 2024-09-19 14:45:05 · 307 阅读 · 0 评论 -
【C/C++】C语言如何实现类似C++的智能指针?
需要注意的是,这仅是一个非常简单的实现,而且在C语言中实现动态内存管理与释放还需要程序员格外小心,以避免诸如内存泄漏和悬挂指针等问题。C语言的动态内存管理与C++中的智能指针相比较弱,更多地依赖程序员手动控制资源的生命周期。等,它们管理着所持有对象的生命周期,可以在智能指针被销毁时自动释放其所持有的资源。在C语言中,虽然没有直接的智能指针概念,但我们可以通过构造类似的功能来模拟智能指针的行为。在C语言中,我们可以创建一种类似智能指针的结构体,并为其提供一些基础的功能,比如自动释放分配的内存。原创 2024-06-04 00:38:11 · 1132 阅读 · 1 评论 -
【C/C++】C语言实现std::move
和完美转发是通过语言的高级特性来实现的,这些特性在C语言中并不存在。因此,C语言中的模拟方法需要更多的手动干预和错误检查。用于将一个对象转换为右值引用,以便可以使用移动语义。在C语言中,我们可以通过传递指针来模拟这种行为。请注意,这些模拟方法在C语言中并不完美,因为它们依赖于程序员手动管理资源和指针。结构体,它包含一个指向整数数组的指针。成员复制到目标数组,然后将源数组的成员设置为。函数来分配内存并初始化数组,以及一个。在这个例子中,我们定义了一个。,这样就模拟了所有权的转移。原创 2024-06-04 00:34:48 · 403 阅读 · 0 评论 -
【C/C++】C语言实现完美转发,亲测实例
在C++中,完美转发(Perfect Forwarding)和std::move是两个不同的概念,但它们都与资源的传递和管理有关。在C语言中,由于缺乏C++的模板和右值引用等特性,我们无法直接实现与C++中完全相同的完美转发和std::move。不过,我们可以模拟这些概念的一些行为。原创 2024-06-04 00:33:53 · 211 阅读 · 0 评论 -
【C/C++】C++完美转发解决了什么问题?
在模板函数中,我们可能需要根据参数是左值还是右值来执行不同的操作。它允许模板函数将参数原封不动地传递给另一个函数,同时保持参数的左值或右值属性。当模板函数需要将参数传递给另一个函数时,如果直接传递,可能会导致不必要的复制。例如,如果模板函数接收一个临时对象作为参数,那么这个临时对象会被复制到函数内部,然后在函数结束时再次被销毁。在C++中,完美转发解决了模板函数在传递参数时保持参数类型不变的问题。可以确保在转发参数时,如果参数是左值引用,它将被转发为左值引用;如果参数是右值引用,它将被转发为右值引用。原创 2024-06-04 00:31:02 · 392 阅读 · 0 评论 -
【C/C++】C++类的六个特殊成员函数,附亲测实例
这些特殊成员函数对于类的正确使用至关重要,因为它们确保了类的资源管理(如内存分配和释放)能够正确执行。在设计类时,应该根据类的需要来决定是否需要自定义这些特殊成员函数。如果类中包含动态分配的资源(如指针、文件句柄等),通常需要自定义析构函数来释放这些资源,以避免内存泄漏。同样,如果类需要支持复制或移动操作,也应该提供相应的特殊成员函数。在C++中,类的特殊成员函数是指那些由编译器自动生成的函数,它们在特定情况下会被调用,以支持类的某些操作。原创 2024-06-02 18:43:08 · 680 阅读 · 0 评论 -
【数据结构】困扰了很多年的问题 -- 链表尾插法为什么要使用 while (p->next != NULL), 而不是 while (p != NULL)
如果我们使用while§来遍历链表,那么当p指向尾部节点时,p->next为NULL,循环就会结束,此时我们无法将新节点插入到尾部节点的后面,因此会导致链表构建错误。= NULL) ,当遍历至链表最后一个元素时,p这个链表节点已然为空,自然不存在链表节点的数据部分以及指针域next部分,自然也就不会再承接尾接新结点的任务了,会导致链表一直构建失败。= NULL)来遍历链表,以确保能够找到尾部节点并将新节点插入到尾部节点的后面。在链表尾插法中,我们需要找到链表的尾部节点,然后将新节点插入到尾部节点的后面。原创 2023-06-25 15:21:54 · 596 阅读 · 0 评论 -
【数据结构】链表带头结点与不带头结点区别
链表带头节点的实现中,在链表头部添加一个额外的节点作为哨兵节点,该节点不存储数据,只用于简化链表的操作。头指针指向哨兵节点,因此链表中的第一个节点为哨兵节点的下一个节点,这样在插入和删除节点时就不需要特别处理头指针,所有节点的操作都可以统一处理。链表不带头节点的实现中,第一个节点即为链表的头节点,因此在插入和删除节点时需要特别处理。但是,带头节点的实现会增加一个额外的节点,占用一定的内存空间。链表带头节点和不带头节点的区别在于: 是否在链表头部添加一个额外的节点作为哨兵节点。原创 2023-06-19 15:20:34 · 1352 阅读 · 0 评论 -
【经典算法】堆排序完美解决 Top K 问题(代码实测可用)
首先将前k个元素构建成一个小根堆,然后遍历剩余的元素,如果当前元素比堆顶元素大,则将堆顶元素替换为当前元素,并重新调整堆,使其仍然满足小根堆的性质。相比于其他解决topk问题的算法,如快速排序、归并排序等,堆排序的优势在于它不需要对所有元素进行完整的排序,而只需要维护一个大小为k的堆,因此在处理大规模数据时,堆排序的效率更高。此外,堆排序的空间复杂度为O(k),相对较小,也更适合处理大规模数据。堆排序的主要优势在于它可以在O(nlogk)的时间复杂度内解决topk问题,其中k为需要找出的前k个元素的个数。原创 2023-05-09 17:18:54 · 148 阅读 · 0 评论 -
【经典算法】C/C++ 实现 LRU 算法 【已实测】
createNode函数用于创建节点,addNodeToHead函数用于将节点添加到链表头部,removeNode函数用于删除节点,moveToHead函数用于将节点移动到链表头部,removeTail函数用于删除链表尾部的节点,createLRUCache函数用于创建LRU缓存,put函数用于向缓存中添加数据,get函数用于从缓存中获取数据,printCache函数用于打印缓存中的数据。考虑缓存块大小:LRU算法只考虑了缓存块的访问情况,没有考虑到缓存块的大小。原创 2023-05-08 16:59:53 · 2046 阅读 · 1 评论 -
【数据结构】C语言实现两链表相加
分别指向两个链表的头节点,使用一个循环遍历两个链表,将对应节点的值相加,并将结果存储到新的链表中。需要注意的是,如果相加的结果大于等于10,则需要进位。最后,如果最高位有进位,则需要在新链表的末尾添加一个节点。然后定义了创建节点和创建链表的函数。该代码中,首先定义了链表节点结构体。函数相加两个链表,并打印结果链表。接着定义了两个链表相加的函数。函数中创建两个链表,调用。和指向下一个节点的指针。,该函数使用了两个指针。,以及打印链表的函数。原创 2023-05-06 14:46:58 · 564 阅读 · 0 评论 -
【奇葩知识】关于常见的 foo(占位符)
使用占位符可以使代码更加简洁和易读,同时也可以避免使用具体的变量名或函数名造成的歧义。在编写示例代码或测试代码时,通常使用这些占位符来代替实际的变量或函数名,以便更清晰地表达代码的意图。在计算机编程中,占位符通常用于表示一个未知的或不重要的变量或函数,以便更清晰地表达代码的意图。等:用于表示一个函数或变量的名称,没有具体的含义。等:用于表示一个整数变量或循环计数器。等:用于表示一个浮点数变量或坐标值。等:用于表示一个字符串变量或文本。原创 2023-04-11 21:03:43 · 357 阅读 · 0 评论 -
Linux内核-关于TCP三次握手
需要注意的是,sock对象的创建过程涉及到三次握手,是TCP协议中建立连接的过程。服务器接收到客户端的连接请求后,调用accept函数接受连接请求,该函数会在内核中创建一个新的sock对象,并将其状态设置为SYN_RCVD。服务器向客户端发送SYN+ACK数据包,客户端接收到数据包后,将sock对象的状态设置为ESTABLISHED,并向服务器发送ACK数据包。应用程序调用listen函数将套接字设置为监听状态,该函数会将sock对象的状态设置为LISTEN,并开始监听来自客户端的连接请求。原创 2023-04-06 22:19:14 · 341 阅读 · 0 评论 -
设计模式-单例模式-懒汉式饿汉式探讨
代码中,使用了单例模式来创建配置管理器对象,保证了整个程序中只有一个配置管理器对象。配置管理器可以使用单例模式来实现,保证只有一个配置管理器实例对象,并提供一个全局访问点来访问该实例对象。数据库连接池可以使用单例模式来实现,保证只有一个数据库连接池实例对象,并提供一个全局访问点来访问该实例对象。日志管理器可以使用单例模式来实现,保证只有一个日志管理器实例对象,并提供一个全局访问点来访问该实例对象。线程池可以使用单例模式来实现,保证只有一个线程池实例对象,并提供一个全局访问点来访问该实例对象。原创 2023-04-06 17:55:49 · 957 阅读 · 0 评论 -
常用数据去重设计
红黑树的空间复杂度比哈希表略高,但是可以支持更多的操作,例如按顺序遍历元素。在红黑树中,元素的去重是通过比较元素的大小来实现的。哈希表是一种基于哈希函数实现的数据结构,可以快速地插入、查找和删除元素。哈希表的时间复杂度为 O(1),但是需要消耗额外的空间来存储哈希表本身。在哈希表中,元素的去重是通过将元素的值作为键值存储在哈希表中实现的。如果需要快速地插入、查找和删除元素,并且可以接受额外的空间消耗,那么可以选择哈希表。如果需要支持更多的操作,并且可以接受略高的空间消耗,那么可以选择红黑树。原创 2023-03-29 18:54:45 · 1174 阅读 · 0 评论 -
红黑树的那些事
红黑树是一种自平衡的二叉查找树,它在插入和删除节点时通过变换树的结构来保持树的平衡,从而保证了树的查找、插入和删除操作的时间复杂度都是 O(log n)。红黑树的节点有两种颜色:红色和黑色。根据红黑树的性质,每个节点要么是黑色,要么是红色。根节点是黑色的,叶子节点(即空节点)是黑色的。如果一个节点是红色的,则它的子节点必须是黑色的。从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑色节点。红黑树的插入和删除操作都需要通过旋转和变色来保持树的平衡。原创 2023-03-27 01:47:23 · 313 阅读 · 0 评论