<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wu___hao的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/wu___hao</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; wu___hao]]></copyright><item><title><![CDATA[单链表之首尾相连，成对输出]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/113530733</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/113530733</guid><author>wu___hao</author><pubDate>Mon, 01 Feb 2021 22:42:32 +0800</pubDate><description><![CDATA[例子：1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;6-&gt;7
输出：1-&gt;7-&gt;2-&gt;6-&gt;3-&gt;5-&gt;4
要求：空间复杂度为O(1)，即不可借助其他容器
思路找到中间的节点将中间以后的节点链接到新的链表头下，反转。然后以头插的形式插入到前半部分的链表中
找到一个链表中的中间节点，我们可以使用快慢指针的方式。即指针s走一格，指针p走两格。当p-&gt;next为空时，此时的s就处于链表的中间位置
申请一个新节点作为头节点，将s以后的链表节点以头插法的形]]></description><category></category></item><item><title><![CDATA[单链表k倍反转]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/113529817</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/113529817</guid><author>wu___hao</author><pubDate>Mon, 01 Feb 2021 21:57:08 +0800</pubDate><description><![CDATA[例子： 1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;6-&gt;7     k=3
输出：3-&gt;2-&gt;1-&gt;6-&gt;5-&gt;4-&gt;7
思路：头插法。要用头插法，就需要给链表定义一个虚拟的头节点。找到局部需要逆转的区域，将其局部反转。但是需要注意的是，当第二次进行反转时，我们仍旧需要一个可以代替头节点的节点，所以我们需要记录每个逆置区域快的第一个节点的指针。因为被逆转后，他将成为局部区域的最后一个节点，同时又是下一个局部区域的头节点。还有一点，如果区域的空间不够]]></description><category></category></item><item><title><![CDATA[单链表的逆置]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/113528515</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/113528515</guid><author>wu___hao</author><pubDate>Mon, 01 Feb 2021 21:10:54 +0800</pubDate><description><![CDATA[单链表逆置：
题目：给定一个不带头节点的单链表，要求将他逆序输出
思路一：
定义三个指针tail、p、s。刚开始的时候tail为空，p指向头节点，s指向头节点的下一个节点。

第一次进循环，让p指向tail空，此时头节点p已经断开了他的指向然后将p赋值给tail，此时tail也指向的头节点(控制前面的链表节点)。将s赋值给p，s往后走(控制后面的链表节点)。

第二次循环，让p指向tail(此时的tail是头节点)也就是让p断开了自己的链接并指向了头节点，将p赋值给tail节点(控制前半部分的链表)，然后吧]]></description><category></category></item><item><title><![CDATA[deepin下linux找不到mysql头文件的解决方法]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/113257493</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/113257493</guid><author>wu___hao</author><pubDate>Wed, 27 Jan 2021 17:37:57 +0800</pubDate><description><![CDATA[在deepin下安装好mysql后，发现在c语言中没有&lt;mysql.h&gt;的头文件。出现了这种情况：
~/Desktop$ sudo apt-get install libmysqlclient-dev
正在读取软件包列表… 完成
正在分析软件包的依赖关系树
正在读取状态信息… 完成
没有可用的软件包 libmysqlclient-dev，但是它被其它的软件包引用了。
这可能意味着这个缺失的软件包可能已被废弃，
或者只能在其他发布源中找到
E: 软件包 libmysqlclient-dev 没有可]]></description><category></category></item><item><title><![CDATA[快速排序]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/110930255</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/110930255</guid><author>wu___hao</author><pubDate>Wed, 09 Dec 2020 19:05:11 +0800</pubDate><description><![CDATA[快速排序的基本思想：通过一趟排序将一组数据分割成独立的两个部分，其中一部分都是比关键字小的数据，另一部分是比关键字大的数据。然后将这两部分再次排序，最终达到序列有序的目的。
从两头开始排序
int Partition(vector&lt;int&gt;&amp; arr,int left,int right)
{
	int i=left，int j=right;//让i和j分别指向数组的0号下标和n-1号下标
	int tmp=arr[i];将0号下标作为关键值
	while(i&lt;j)//当i小于j时]]></description><category></category></item><item><title><![CDATA[查找排序二叉树的最小值，最大值，Next指针,并逆序打印]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/110307423</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/110307423</guid><author>wu___hao</author><pubDate>Sun, 29 Nov 2020 11:46:55 +0800</pubDate><description><![CDATA[给出一个排序二叉树，求它的最小值，最大值，Next域
思路：一个排序二叉树，如果要将它从小到大排序，只需要按照中序遍历规则打印即可。那么它的第一个元素就是它的最小值，而最后一个元素就是他的最大值。
最小值：
BstNode* First(BtNode* ptr)
{
	while(ptr!=NULL&amp;&amp;ptr-&gt;left!=NULL)
	{
		ptr=ptr-&gt;left;
	}
	return ptr;
}

最大值:
BstNode* Last(BstNode* ptr)
{]]></description><category></category></item><item><title><![CDATA[二叉树的插入与删除]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/110304669</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/110304669</guid><author>wu___hao</author><pubDate>Sun, 29 Nov 2020 11:12:11 +0800</pubDate><description><![CDATA[排序规则：定义一个vector数组，将数组中的第一个值作为根节点，此后将后面的值与根节点的值比较，如果小于根节点的值，则放在根节点的左边，如果大于根节点的值，放在根的右边。以此类推，根节点的左子树(右子树)又是一棵二叉树。此外，在二叉树排序中不允许出现两个相同的值。当二叉树完成之后，可以用中序遍历的方式将它从小到达排序。


定义结构体BstNode和BSTree分别定义了它们的属性和根节点，这里会增加一个双亲指针，它可以让我们的子节点指向它的父节点，但是这样也会降低它的存储密度。即原来12个字节中可以存储]]></description><category></category></item><item><title><![CDATA[二叉树的遍历]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/109906955</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/109906955</guid><author>wu___hao</author><pubDate>Sat, 21 Nov 2020 21:59:15 +0800</pubDate><description><![CDATA[二叉树的结构设计：
typedef char ElemType;
typedef struct BtNode {
	struct BtNode* left;//左节点
	struct BtNode* right;//右节点
	ElemType data;//数据域
}BtNode,*BinaryTree;

二叉树的遍历方式：
1.前序遍历
访问根节点
前序遍历左子树
前序遍历右子树
void Psoder(BtNode* ptr)
{
	cout&lt;&lt;ptr-&gt;data;
	PsOder(]]></description><category></category></item><item><title><![CDATA[智能指针]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108506243</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108506243</guid><author>wu___hao</author><pubDate>Sat, 12 Sep 2020 20:11:59 +0800</pubDate><description><![CDATA[引言：在C++中，堆内存的管理都是由在栈上开辟的变量名间接控制的。这是因为在堆上开辟的空间是没有名字的，我们无法直接对齐进行控制。所以当释放该堆内存时，也需要我们去人为的释放它。
智能指针的出现就是为了解决上面的问题，当释放一个堆内存时，它将由系统释放，而不是我们人为的释放它。这样就会避免许多内存泄漏的产生。
只能指针总共分为4种：
C++98  auto_ptr
C++11 unique_ptr		shared_ptr		weak_ptr
auto_ptr
特点：
1.所有权唯一（即一个堆内存只能有一个指]]></description><category></category></item><item><title><![CDATA[TCP协议的概念以及和UDP协议的区别]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108318545</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108318545</guid><author>wu___hao</author><pubDate>Mon, 31 Aug 2020 12:11:57 +0800</pubDate><description><![CDATA[TCP协议的基本概念
TCP的全程是Transmission Control Protocol
1.TCP协议为应用程序提供了可靠的、端到端的、面向连接的字节流通信的协议
2.利用网络层IP协议提供的不可靠的分组传输服务，用来解决的重传和排序问题
字节流：应用程序对数据的发送和接受没有边界限制
面向连接：在传送数据之前，明确知道接收方的存在以及传输的一些性质（缓冲区的大小，发送序号的初始值）
Unicast：只支持两端点之间的通讯，不支持多播(Multicast)和广播(Broadcast)面向字节流的流逝]]></description><category></category></item><item><title><![CDATA[http协议以及和https协议的区别]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108306389</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108306389</guid><author>wu___hao</author><pubDate>Sun, 30 Aug 2020 16:42:58 +0800</pubDate><description><![CDATA[http
http协议是一种超文本协议，它在应用层通过TCP协议来实现其功能。它的端口号为80号端口
当一个浏览器向服务器端请求链接时，首先会进行三次握手。建立链接后浏览器会给服务器发送一个http报文，服务器也会回给浏览器一个http报文。
假设客户端在浏览器中输入“www.baidu.com”，通过dns可以找到输入网址(域名)对应的IP地址
服务器：从硬件上来讲是一台电脑，从软件上来讲是一个进程(程序)
浏览器向服务器发送一个(http)的请求报文，结构如下：
方法：请求的资源(网页)+版本号
客户端]]></description><category></category></item><item><title><![CDATA[守护进程]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108298651</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108298651</guid><author>wu___hao</author><pubDate>Sat, 29 Aug 2020 20:48:19 +0800</pubDate><description><![CDATA[守护进程
特点：
1.在后台运行，不需要和用户进行交互
2.运行周期长，在计算机启动时开启，计算机关机时关闭。
在一般的进程中终端关闭时，会话也会随之消失。但是守护进程要在后台运行，而且运行周期长，所以需要设计一个不依赖终端的进程，所以一般会给会话创建一个新的会话，将守护进程放在新会话中。
了解守护进程，需要知道这四个概念：
1.会话：伴随着终端的打开而产生，随着终端的打开，会和内核建立一个会话。
2.会话首进程：终端打开后产生的第一个进程就是会话首进程(一般都是bash进程)
3.进程组：创建进程的时候会]]></description><category></category></item><item><title><![CDATA[TCP的可靠传输之滑动窗口]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108290126</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108290126</guid><author>wu___hao</author><pubDate>Sat, 29 Aug 2020 09:48:22 +0800</pubDate><description><![CDATA[滑动窗口
TCP中的滑动窗口是以字节为单位来发送的。假设现在有两个窗口A和B，其中A窗口向B窗口发送数据，B窗口接收到数据并返回一个确认报文。

其中用红色框框出来的字节数就是滑动窗口的大小，滑动窗口的大小取决于B窗口缓存区的大小。滑动窗口越大，说明效率越高。就像拿杯子去接水一样，杯子越大，水管的水流量就越粗。所以说滑动窗口实质上是用来负责流量控制的。
前面的1234四个字节是已经发送且对方成功接受的数据，第五个字节是B期望的下一个字节。在滑动窗口中的字节都可以发送出去，但是要保留一会儿等待接受区去接受，如]]></description><category></category></item><item><title><![CDATA[TCP状态转移图]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108285830</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108285830</guid><author>wu___hao</author><pubDate>Fri, 28 Aug 2020 21:05:20 +0800</pubDate><description><![CDATA[以下主要讲的是TCP从建立到关闭的整个流程图。
SYN：建立链接
FIN：关闭连接
ACK：响应，确认号
PSH：tcp缓存区读取数据
ISN：初始化序列号
RST：重新建立连接
URG：紧急指针是否有效

1.服务器端运行，socket套接字处于LISTEN状态
2.客户端主动发送SYN，此时变为SYN_SENT状态
3.服务器端收到客户端发送的SYN以后，会给客户端发送自己的SYN和ACK，此时变为SYN_RCVD状态
4.客户端收到服务器端发送的SYN和ACK，发送ACK进行确认
5.服务器收到ACK]]></description><category></category></item><item><title><![CDATA[继承与多态]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108196766</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108196766</guid><author>wu___hao</author><pubDate>Wed, 26 Aug 2020 20:10:18 +0800</pubDate><description><![CDATA[继承
继承的本质是复用，也就是沿用父类的变量和作用域，并对其做出的扩展。它会使用一个叫做继承列表的符号（：）来将两个类链接起来。例如：
class student : public people，就是在student类中沿用并扩展了people类。
在习惯上我们将被继承的类叫做基类（父类），继承的类叫做派生类（基类）。
派生类（子类）=》基类（父类），派生类继承了基类
基类=》派生类，基类派生了派生类
继承的方式有三种：
public：共有（任意位置）
protected：保护（子类类和本类类）
priva]]></description><category></category></item><item><title><![CDATA[通过命令提示符查看c++中类的构造]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108196923</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108196923</guid><author>wu___hao</author><pubDate>Mon, 24 Aug 2020 12:38:41 +0800</pubDate><description><![CDATA[第一步：在电脑中搜索vs，会出现下面内容（交叉工具命令提示符）：

输入当前路径：

输入dir，找到我们的（继承.cpp）：

输入cl -d1reportSingleClassLayout(clasname) (XX.cpp) /EHsc,我们在本例中的类是（derve）,类名是（继承.cpp）
cl -d1reportSingleClassLayoutderve 继承.cpp /EHsc，最终结果如下：


...]]></description><category></category></item><item><title><![CDATA[String类中的写时拷贝函数]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108181229</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108181229</guid><author>wu___hao</author><pubDate>Sun, 23 Aug 2020 12:22:14 +0800</pubDate><description><![CDATA[拷贝函数
拷贝函数分为浅拷贝和深拷贝，浅拷贝是系统自带的一个函数，它的功能是让两个指针指向同一块内存空间来实现内存共享。深拷贝函数是用户根据需求自定义的一个函数，它的功能是让每个对象都有一块独立的内存空间。
写时拷贝就是集合了浅拷贝和深拷贝的特性，当我们在调用点只做访问时，用浅拷贝就行。当我们要在调用点修改已存在对象的某个字符时，调用深拷贝函数。
设计思想：定义一个计时器，计时器存放在字符串中。每将一个已存在的对象赋值给新对象时，计时器自加；当调用点需要改变某个自负床中的一个字符时，就调用深拷贝来开辟一块新]]></description><category></category></item><item><title><![CDATA[函数模板和类模板]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108170123</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108170123</guid><author>wu___hao</author><pubDate>Sun, 23 Aug 2020 00:02:39 +0800</pubDate><description><![CDATA[函数模板
函数模板：template &lt;&gt;，&lt;&gt;是模板类型参数列表，&lt;&gt;里面放着类型，它是由typename/class定义而来。但是我们在定义时一般不会用class来定义，因为这会使我们很容易误认为这时一个类模板。它是在编译阶段处理的，也就是说在编译阶段会将代码展开，将typedef T替换成我们需要的类型，所以这其实是一个类型重定义的过程。
模板函数与函数模板
函数模板是一个模板类型，而模板函数是指一个函数。模板函数是函数模板在调用点实例化后生成的。读起来有点绕口，所]]></description><category></category></item><item><title><![CDATA[消息队列]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108146722</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108146722</guid><author>wu___hao</author><pubDate>Fri, 21 Aug 2020 15:02:38 +0800</pubDate><description><![CDATA[消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块中，都包含了一种数据类型。我们在消息队列中获取消息时，可以指定它的类型进行获取。

每个消息中都有一个结构体struct mess{};它里面有一个长整型类型，在里面你可以定义自己想要的数据。
消息队列中有四种方法：msgget创建消息  msgsnd添加消息  msgrcv获取消息  msgctl修改消息，原型如下：
*int msgget(key_t ket,int msgflg);
int msgsnd(int msgi]]></description><category></category></item><item><title><![CDATA[管道及其简单实现]]></title><link>https://blog.youkuaiyun.com/wu___hao/article/details/108129559</link><guid>https://blog.youkuaiyun.com/wu___hao/article/details/108129559</guid><author>wu___hao</author><pubDate>Thu, 20 Aug 2020 18:56:47 +0800</pubDate><description><![CDATA[管道
管道也叫管道文件，是文件的一种。其中分为有名管道和无名管道，有名管道：可以在任意两个进程间通信；无名管道：只能在父子进程间通信。管道的通信方式是半双工的，那么什么是半双工呢？就像收音机、打印机一样。那既然有半双工，当然也会有全双工，全双工就向电话一样双方都可以进行通话。
管道分为读端和写端，顾名思义，写端就是向管道中写入数据，读端就是向管道中读取数据。
有名管道
首先我们通过mkfifo fifo来创建一个管道，接着我们分别创建出读端和写端。
对文件进行进行操作的方法有三种，它们分别是：O_EDONL]]></description><category></category></item></channel></rss>