![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 59
暗色光
学无止境,欢迎交流
展开
-
通俗易懂的图解二叉搜索树、AVL树和红黑树
搜索是一种很常见的需求,当数据较多时,如何找到目标对象时,即需要搜索查找。那么如何快速找到目标呢,最朴素的思想就是暴力查找,一个一个对比。显然,当数据量增大时,我们需要优化查找方法获取更快的查找速度,我们可以通过维护一个有序数组,从而实现二分查找,查找速度从O(n)降为O(longn)。但是数组并不便于插入和删除,链表便成为了最好的选择。既然是采用二分查找,那么不如直接按照查找的步骤维护一种数据结构,于是二叉搜索树出现了。二叉搜索树的性质为:若左子树不为空,则左子树上所有节点值都小于根结点值;原创 2022-07-06 21:21:02 · 451 阅读 · 1 评论 -
C++智能指针
由于使用malloc、new在堆上申请空间后,容易忘记释放对应空间,C++提出了智能指针管理申请的内存,避免内存泄露。RAII(Resource Acquisition Is Initialization),是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。.........原创 2022-06-07 16:28:03 · 320 阅读 · 0 评论 -
webserver之定时器
前言此博客记录对于TinyWebServer项目的学习,并根据自己的理解做出些许更改。原项目地址:https://github.com/qinguoyi/TinyWebServer定时器网络程序通常需要处理定时事件,例如定期检测客户连接的活动状态,因为非活跃连接占用了连接资源,需要定期检测释放非活跃连接。通常将定时事件封装为定时器类,然后使用排序链表、时间轮等数据结构管理定时器。linux提供了三种定时方法,1.socket选项SO_RCVTIMEO和SO_SNDTIMEO2.SIGALRM信原创 2021-11-12 17:02:50 · 2052 阅读 · 0 评论 -
排序算法——十大排序算法的图示与实现
十大排序算法概览比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。前七种为比较类排序,后三种为非比较类排序。稳定性:如果a=b,且a在b前面,排序之后仍能保证a在b前面,则为稳定的。插入排序逻辑将左端第一个元素视为有序,然后遍历后面的元素,逐步插入到有序序列中。代码实现//插入排序void原创 2021-11-12 16:59:52 · 1306 阅读 · 0 评论 -
webserver之日志系统
前言此博客记录对于TinyWebServer项目的学习,并根据自己的理解做出些许更改。原项目地址:https://github.com/qinguoyi/TinyWebServerLog日志系统是用来存储程序运行中的通知信息、warning、error等。首要任务就是格式化输出字符串到一个文件,还应当记录消息产生的时间,此系统选择使用按天作为文件名。以消费者-生产者模式,使用阻塞队列实现线程异步处理Log消息。还实现了主线程同步处理Log消息。Log.h从头文件可以清楚看出Log类具有的功原创 2021-09-29 15:45:41 · 1457 阅读 · 1 评论 -
webserver之使用数组实现阻塞队列
阻塞队列阻塞队列特性,当队列中没有元素时,对这个队列的弹出操作将会被阻塞,直到有元素被插入时才会被唤醒;当队列已满时,对这个队列的插入操作就会被阻塞,直到有元素被弹出后才会被唤醒。queue容器在程序结束时才会释放内存,deque可以动态释放,也可使用new分配容器再使用delete释放,vector* vec_ptr = new vector;delete vec_ptr;使用数组实现可以预留出固定大小的内存,个人理解使用数组的优势所在。代码实现#ifndef BLOCK_QUEUE_原创 2021-09-28 09:52:39 · 219 阅读 · 0 评论 -
线程同步的三种机制
线程同步线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态。即是避免同时操作变量,产生冲突。POSIX信号量信号量大于0时,等待信号量的线程被唤醒sem_init(sem_t* sem, int pshared, unsigned int value)初始化信号量,默认为进程共享的,pshared = 0指定为局部信号量,value为初始值sem_wait(sem_t* sem)阻塞原创 2021-09-24 19:35:17 · 1392 阅读 · 0 评论 -
剑指Offer14-剪绳子1&2
题目描述–剪绳子1思路分析首先要分析出怎么切分是最优方案,显然和一定时,分成相等的数的乘积最大。用简单的数学归纳的思想可以发现,4对应2*2,5对应2x3,6对应3x3,7对应3x2x2,8对应3x3x2,显然分为3是最优选,然后是2。由不等式也可解出极值点是e约为2.7,距离3最近。动态规划首先最直接会想到用动态规划的思想解题,先考虑切3,判断切3后的值是否大于dp中对应的值,依此向前填充dp矩阵,然后考虑切2int cuttingRope(int n) { if(n &l原创 2021-08-24 12:38:02 · 92 阅读 · 0 评论 -
深度优先搜索(解题剑指Offer12、13)
剑指Offer12-矩阵中的路径 题目描述思路分析显然这是一个深度优先搜索的题,遍历整个矩阵寻找word的首字母,然后对首字母位置的上下左右四个方向进行延展,判断第二个字母是否存在,依此方法直到找到整个word字符串,即为true。为了避免重复遍历某个位置,在一条分支走过该位置时将其置为数字等不影响的字符作为标记,由于不同分支互不影响,所以在该分支结束时需要将标记恢复。代码bool exist(vector<vector<char>>& board, string原创 2021-08-21 16:30:46 · 68 阅读 · 0 评论 -
Select网络模型下的简单CS实例
Select网络模型Select模型属于IO多路复用模型的一种,select使用一个socket数组来存放连接的socket。select会监视数组中所有的socket,可以知道哪些socket可读或者可写,从而避免无效操作(例如去读取不可读的socket,而在select中可以先查询该socket是否可读)。这样多个socket的IO操作能在一个线程内并发交替完成,这就是IO多路复用(复用同一个线程)。使用select模型实现的简单服务端与客户端服务端代码#define WIN32_LEAN_A原创 2021-07-19 20:41:31 · 173 阅读 · 0 评论 -
快速幂算法
快速幂算法假设求pow(2, 20),一次一次的累乘非常耗时间,需要进行20次运算。将指数20使用二进制表示为10100。则2^20 = 216*24可以看出每当二进制位为1时将对应2的幂指数乘到结果上即可。从最低位开始迭代,在迭代时将底数进行自乘,可得到对应的幂。而计算机存储数据时正是以二进制存储的,使用二进制不需要进行转换,对于指数需要判断它的最低位是否为1,然后将其右移一位继续判断,直到指数为0。代码实现double quick(double x, long long n) { dou原创 2021-07-06 19:37:13 · 110 阅读 · 0 评论 -
windows简单TCP通信 C++
尝试使用自定义struct和char发送信息。服务器根据客户端发送的不同消息进行回应。在发送struct时先发送一个“Who”以便客户端确认。服务器#define WIN32_LEAN_AND_MEAN//#define _WINSOCK_DEPRECATED_NO_WARNINGS#include<windows.h>#include<WinSock2.h>#include<stdio.h>#include <WS2tcpip.h>原创 2021-07-04 20:30:51 · 657 阅读 · 0 评论