自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(41)
  • 收藏
  • 关注

原创 unordered_map, unordered_set, bitset位图(表),布隆过滤器

前面我们就说明了unordered_map与unordered_set的底层容器是hash表;现在我们就来看看它们究竟是如何实现的:和map与set一样,因为RBTree为了适配两种容器,需要一些改造;所以这里的hash表也需要改造;

2024-04-29 10:21:31 592

原创 哈希表功能及底层讲解与实现

hash表的结构有开散列和闭散列两种,这两种结构都可以减轻hash冲突的问题,开散列通过增加hash桶高度来解决,而闭散列通过控制荷载因子,使得hash表中总是存在部分空闲空间提高,数据存储的命中率来减轻hash冲突;这两种方式中,由于闭散列总是要留出一部分空闲空间的原因,使得开散列的平均空间利用率还是高于闭散列的(优化算法也发挥着作用),而且开散列增加的是指针,但闭散列增加的是节点,节点的空间是远大于指针的;hash表的哈希函数有很多;

2024-04-19 10:57:43 538

原创 map与set oj题

本题要求复制随机链表;本题有两种写法;方法1:(使用C语言)思路:因为我们在复制链表的时候,还需要将复制的随机节点的指针也复制到复制节点中;所以重点是如何知道某个复制节点是我们复制的随机节点;我们可以改变原有链表,将复制的节点链接在原有节点的后方,这样我们的原有节点和复制节点就是一一对应的了:形成这样的链表之后,我们就可以通过原链表节点的cur->random->next找到我们cur->next的复制的随机节点位置,从而更新复制节点随机节点值;

2024-04-18 09:41:23 588

原创 进程间通信,管道,匿名管道,共享内存,信号量

在我们的命令行上输入的 | 符号就是匿名管道,通过它可以实现我们进程之间的数据交流;首先我们需要明白管道的存在是为了进行进程间通信,而想要进程间通信,我们首先需要进程可以有数据交流,而想要让进程有数据交流,就得让进程看到同一块内存空间;而管道就是那块被双方进程都可以看到的内存空间;所以叫管道的进程间通信我们首先要创建出我们的管道;上图中的管道就是创建出来供进程交流的内存,这个内存的生命随着交流双方的关闭会自动消失;

2024-04-17 08:57:16 917

原创 map与set

set在我们就是我们前面学习的k模型,它可以用来比对数据,增删查的时间复杂度都是O(logn)效率非常高,由于它底层的原因,它也可以实现排序,通过中序遍历可以输出我们的有序的数据;又因为它的T值在插入的时候具有唯一性的原因,set还有去重的作用;

2024-04-14 16:23:02 819

原创 红黑树实现及原理

前面我们学习了AVL树,而AVL树对于树高度的检查非常严格,这样的好处是我们树的查找效率非常高,但是这样严格的检查,会导致我们树的插入,删除这些操作效率会低一些(因为AVL树的旋转非常的频繁);所以因为这个原因,出现了一种对数高度检查相对于AVL树要开放一些的树——红黑树;红黑树的效率分配较为均匀,使得插入,删除,查找都具有不错的效率;红黑树也好二叉树也罢它们本质都是搜索树,只是通过不同的方式和标准来平衡我们的二叉树,使得我们的搜索二叉树不会出现歪脖子树的情况;

2024-04-11 16:22:22 786

原创 C++ AVL树(旋转)

我们之前学习了搜索二叉树,我们知道普通的搜索二叉树会有特殊情况出现使得二叉树的两枝极其不平衡形成我们通俗说的歪脖子树:这样的树一定会使得我们的增删查的效率变低;为了避免这种极端的情况出现,在1962年有两位伟大的俄罗斯数学家和发明的;它们通过旋转使得我们的树的任意节点的左右子树高度差不超过2;使得搜索二叉树总会是一颗平衡的搜索二叉树;我们怎么知道我们的左右子树的高度差呢?

2024-04-02 11:06:01 1051

原创 搜索二叉树

搜索二叉树是接下来要学习的map和set的基础,它和我们之前学习的priority_queue的二叉树结构相同;当搜索二叉树进化为平衡搜索二叉树的时候,时间复杂度可以优化为O(logn);效率非常高;

2024-03-19 15:38:18 844

原创 二叉树oj练习

(牛客,力扣题目)

2024-03-18 11:10:20 886

原创 C++多态

了解了这些之后,我们来对比一下我们学的一些概念:重载:在同一区间内,通过符号表中的命名规则(参数不同)可以使得同名函数存在;重写(覆盖):在子类虚函数和父类虚函数返回值,名字,参数都相同(除开两个例外);重定义(隐藏):在子类继承了父类的成员函数时,如果子类写了同名函数(重写除外)就会形成隐藏,从而显示调用只会调用子类的成员函数;

2024-03-12 17:30:40 655

原创 磁盘,Linux文件系统,动静态库,软硬链接

在我们前面的学习中,我们知道了我们进程是如何打开文件的,如何将数据写入我们的文件中的;现在我们拓展我们的思维,我们的数据写入我们的文件中,而文件在我们的磁盘中存储着,那数据是怎么进入我们的磁盘中的呢?

2024-03-11 19:05:22 699

原创 C语言文件操作,linux文件操作,文件描述符,linux下一切皆文件,缓冲区,重定向

为什么我们可以把文件创建在进程当前路径中,当前路径到底是什么意思?我们在运行可执行程序后程序变成了进程,而进程在我们之前的学习中,我们知道进程有进程的pcb结构体,这个结构体中存放了进程的各种信息,那么我们运行进程时所在的路径也会被记录下来,这个路径就是当前进程所在的路径,也就是当前路径的根本意义;下面我们通过实际现象来证明我们思路:由此我们可以清楚的明白所谓的当前路径就是存储在进程的pcb结构体中的进程信息,我们只要通过查找进程的结构体就可以找到我们的当前路径;

2024-03-04 17:06:40 1107

原创 C++继承

因为我们的子类和父类是两个类中的所以是处于两个不同的作用域中,所以子类和父类相同名字的成员(成员名字相同即可,成员函数也是函数名相同即可)不是重载行为而是重定义/隐藏行为;class Apublic:cout << "我是A的print函数" << endl;public:cout << "我是B的print函数" << endl;cout << "b._a输出了 " << b._a << endl;

2023-12-21 23:21:15 857

原创 进程控制:进程创建,进程终止,进程等待,进程替换,模拟实现shell

而代码和数据都是我们在写父进程的代码的时候所输入或者说所产生的,这些东西是我们写的,而pcb结构体是操作系统创造出来的,所以子进程的pcb结构体必定是独立的,是自己独有一份的(进程独立性也满足),而代码一般我们是只读不修改与写的所以我们的代码一般子进程与父进程是共享的,剩下的数据数据是可读可写的,我们进程分流的时候,当数据发生改变时才会分离(写时拷贝);上面我们学习了怎么创建怎么等待进程,这些其实都是为了让我们的进程为我们做事,我们需要做的事情在子进程中实现,这样我们的父进程就可以去做其他的事情;

2023-12-18 15:56:21 910

原创 栈,队列,优先级队列(堆),deque

我的博客起到的是指引思维的作用(也就是为什么这个容器要这么做),而基础的对stl容器的讲解(也就是容器是做什么的)你应该直接去看权威的文档会的了解的更透彻;看不懂就用翻译软件一个一个的翻译。

2023-11-20 16:34:11 49

原创 模板参数,模板特化,模板的的分离编译要求

模板的存在促进c++的泛型编程,优化了编写代码的效率,stl容器也是因模板而生的;但是同时也提高了我们学习的成本,让c++难度迈上一个新台阶;2023.11.19。

2023-11-19 18:54:37 54

原创 可执行程序是如何运行的,进程地址空间(虚拟/线性)

地址空间这一概念,我们在以往的学习中肯定是有这么一个概念的,如果记忆有点模糊,那看看下面这个图也应该懂了:现象:我们使用代码证明出来了我们这些数据的地址;这些地址确实是按照我们上面的图片所示排布的,我们的地址空间也确实可以这么划分!

2023-11-17 20:31:30 55

原创 stl_reverse_iterator反向迭代器

我们可以看到反向迭代器的模板参数有三个,后面两个在我们讲list的迭代器的时候我们就讲过了,我们现在就看这个第一个模板参数iterator,这个模板参数就像它的名字一样,它就是迭代器,我们的模板参数居然是一个迭代器!而我们传递迭代器作为模板参数,这样我们就是对我们的迭代器进行操作了,既然是对迭代器进行操作,那这样的话所有容器都有迭代器,而且迭代器提供的接口都是一样的(因为迭代器是所有容器都有的,通用的工具的实现的接口一定是相同的)所以我们反向迭代器的实现以迭代器为底层也可以实现通用!

2023-11-16 15:40:38 30

原创 C++stl_list 链表

链表早在我们学习数据结构的时候就已经学习过了,我之前在学习数据结构的时候和我上一篇vector一样是用c语言实现的,那个时候写的代码又臭又长,要满足许多接口;打开链接就可以找到我的stl模拟实现代码实现因为我们上一篇就讲了为什么要有stl容器的原因,这次我们就直接进入正题,我们直接来看我们的stl_list;打个预防针:我们list中迭代器的运用非常巧妙要做好心里准备;stl_list文档:使用文档辅助学习效率更高哦!

2023-11-10 10:52:18 62

原创 环境变量linux;main函数的三个参数

相信环境变量这个词,我们或多或少都听过,我记得我第一次听到环境变量这个词是在java课程中老师让我们为我们的java命名配置环境的时候;有了这个环境变量,我们在任何地方都可以使用我们的java命令;那为什么会出现这种情况呢?我们将我们的java命令的路径放到了这个变量中,而我们运行命名就是通过环境变量PATH这一变量中存储的路径找到我们命令所在的文件,以此我们就可以运行我们的命令了;接下来我们做一下实验来论证我们的理论:这是我创建的test.c文件的代码我们将它编译成可执行程序。

2023-11-09 11:11:38 30

原创 C++STL_vector顺序表

我们在之前学习数据结构的时候一定是接触过vector的它就是我们数据结构中的顺序表,我们之前使用C语言实现过C语言模拟实现vector · 小六/my_road - 码云 - 开源中国 (gitee.com)这是我使用C语言实现vector的代码;我们在实现vector的时候要写一大堆东西;每次要使用顺序表这样的数据结构的时候我们都需要自己手搓一个顺序表出来,或者是复用自己写过的顺序表;这样的过程一定是麻烦的;

2023-11-08 09:35:56 25

原创 计算机结构,操作系统管理,进程

在进入本篇前我们先模拟一个场景,在我们日常使用qq这个软件的时候,我们是怎么使用它来传递信息的,为什么我们在自己的手机上输入了一段信息点击发送,你发送的对象在短短几秒内就能收到你的信息呢?这样信息传递的过程是什么?要搞清楚这个过程我们需要从源头说起;

2023-11-07 09:35:17 43

原创 在linux下如何调试代码

之前的博客,我们学习了如何在linux下编写和将代码编译成可执行程序;接下来,我们来学习在linux下如何调试我们的代码;我们需要使用gdb工具;

2023-10-17 19:20:29 98

原创 string类

string就是字符串的意思,其实我们在C语言阶段就经常接触字符串,那个时候我们对于字符串进行处理都是使用C语言库中的str函数来对字符串进行处理,当我们需要对我们的字符串进行增删查改的时候,这个时候就需要我们自己使用str这些函数来对字符串进行处理了,我们在处理这些函数的时候对于字符串的访问也需要注意使用的规范避免安全问题,我们这样使用str是可以实现我们对字符串的管理的,但是我们这样的操作并不方便,也并不安全;

2023-10-15 17:05:42 36 1

原创 linux下如何下载软件以及如何git

我们在日常使用电脑和手机时最最常使用的一定是app,软件,有了这样的软件为我们提供服务,正是它们的存在便利和丰富了我们的生活;那我们是如何得到这些app的呢?我们的app一定都是需要下载的不可能是凭空出现的;我们如果想获得app,我们是不是需要到我们的手机应用市场或者是浏览器上搜索下载呢;我们的yum就是类似于应用市场这样的软件;它将许多的软件包进行统一管理;我们可以通过yum在linux上寻找我们需要的软件,然后进行下载,获取服务;其实yum操作非常简单,就是一条指令就可以下载我们的软件;

2023-09-28 16:26:14 709 1

原创 模板=函数模板+类模板

我们在写C语言的时候对于函数我们传参时类型一般都是固定的,所以我们写的函数在接收参数时我们的形参也得随之改变,这样就导致我们的函数总是需要变换,使得我们得写不同的函数来接受不同类型的参数;这可是我们这样的函数只是传输的类型有所不同而已,函数的实现逻辑并没有变化;看这些代码,我们完全可以发现它们仅仅只是函数参数不同,其他完全相同,这样的代码无疑是非常低效的;我们是否可以写出我们的函数实现相同,只是参数类型不同的函数呢?是的这就是我们的函数模板;

2023-09-26 21:34:05 43

原创 C++内存管理

今天我们讲的内存是我们旧机器运行时所使用的内存,这些内存又会被划分为了几个区域,这些区域的用法是不同的;

2023-09-26 10:09:25 36

原创 如何在linux下运行代码

我们的代码通过vim等软件编写好后,它此时是.c或者是.cpp文件;我们如何将这个文件变成可执行文件呢?这个时候我们就需要使用gcc和g++指令了;

2023-09-25 15:35:00 666 1

原创 如何在linux下编写代码

在新手学习的过程中,我们是不是都在使用如vs,codeblocks这样的软件来编写代码,这样的软件包含了预编译,编译,汇编,链接于一体,可以直接运行我们的代码;可是我们有没有想过为什么我们输入一串代码计算机就能执行相应的命令呢?我们多多少少都知道机器只会读01两种高低电平的信号,我们的代码却是很长的一串字符,我们如果想要我们的硬件明白我们的指令,那我们就需要把我们的指令转换为机器读的懂的电信号01,这个时我们的电脑就会相应的运行;

2023-09-19 16:07:11 855

原创 Linux操作系统——权限

原因是在公司中我们的项目往往是许多人一起分工合作的,我们每个人负责每个人相应的部分,如果每个人都可以更改与操作我们项目中的所有文件,那么我们的数据一定会面临各种风险与问题,所以这个时候我们就需要权限来限制每个人,让每个人各司其职,限制每个人所操作的区域;大家认为我们平时在用电脑的时候有没有在直接使用windows操作系统呢?是不是在思考我们平时点击app打开app这些操作是不是属于使用操作系统呢?其实我们这并不是在直接使用操作系统;

2023-09-17 19:29:31 64 1

原创 Linux基础指令

小tip:选项是可以不使用的,每个指令都有它的默认选项以下命名的说明,我都进行了实践操作,加以我自己的理解和官方解释加以实现。

2023-09-15 20:05:50 60 1

原创 Linux历史,为什么要学习linux

linux是非常重要的一个操作系统,我们c++的学习者必不可少的都需要学习它;但我们为什么需要学习它呢?我们需要从它的历史开始说起;

2023-09-13 22:35:43 60 2

原创 初始化列表,static成员,友元,匿名对象,拷贝构造的优化

我们对于构造函数除了我们自己写的构造函数,和默认构造函数之外,还有一种我们不写自动生成的构造函数,我们之前说到这种构造函数会自己去对我们的自定义构造函数进行初始化;但是这个初始化的地方在哪里呢?到底如何去调用我们自定义类型成员它的构造函数呢?

2023-06-02 16:01:14 47

原创 运算符重载,const成员

如果我们的运算符重载写在类的外面时我们无法调用类里面的私有成员,我们如果要使用类里面的私有成员的话,我们可以把我们的运算符重载写成我们的类的成员函数,这样我们就可以使用类里面的成员了;上一章我们说的隐藏函数还有两个就是我们的运算符重载里面的=与&操作符它们两个操作符如果我们不显示实现的话我们的编译器会自动生成运算符重载,所以我们的这两个操早作符重载只能作为我们类的成员函数来进行操作符重载,否则我们类自动生成的操作符重载会与全局的操作符重载冲突;但是我们其他的运算符函数并不会默认实现的;

2023-06-02 09:09:38 45

原创 类的构造,析构,拷贝构造,赋值运算符重载,const成员

总结:我们的构造函数在普通的只含有内置类型成员的类中是不需要自己写构造函数的,或者是在含有自定义类型成员的类中,我们的成员自己含有构造函数(当然这个构造函数一般是我们自己写的就比如MyQueue)这样我们编译器自己生成的默认构造函数就会去调用我们成员的构造函数,这些是不需要我们写构造函数的类,而需要我们写构造函数的类一般是创造了新的空间的类,他的空间需要我们来创造编译器不懂如何创造(就比如Stack,Queue);我们的默认构造函数可以分成无参构造函数,全缺省构造函数,我们没有写编译器自动生成的构造函数;

2023-06-01 12:19:03 38

原创 什么是类和对象,类的基本内容,this指针

面向对象,我们可以理解为对某个对象进行任务分配由这个对象来完成任务;面向过程就是我们把我们需要完成的目标分成多个过程然后一个一个去完成它;我们的C语言就是一门面向过程的语言,它一般把我们需要完成的目标分成很多个过程,这个过程就是一个个函数,函数中的数据等都需要指定;而我们的c++是基于面向对象的,它把我们需要做的事情封装了起来,我们需要完成的的目标可以分配给封装了的对象让这个对象进行操作;所以我们可以知道基于面向对象的是C++,面向过程的是C语言;类在我们c++中是这样定义的。

2023-05-30 08:53:48 32

原创 c++学习的前提内容,c++基础

在我们写c++或者c时我们写的第一个程序应该就是hello world。写c时我们使用printf函数需要调用C语言自己的函数库inlude,这样我们就可以使用printf函数将我们的字符串打印到我们的屏幕上面了。在我们的c++中我们的大佬们为了弥补C语言的一些不足添加了一些其他的库。于是我们就可以使用cout来打印我们的字符串。但当我们刚刚开始看见下面的代码时我们肯定都会好奇这个cout函数前面的std::是用来做什么的。这就是c++所引入的新事物———命名空间。

2023-05-29 09:15:06 66

原创 通讯录实现

当我们打扫干净新房子之后我们要搬进去住了,我们开始往这片空间添加数据,我们如下面代码一样一个一个输入我们的信息进入空间如果我们多次输入时发现有重复的数据我们就会提示已存在联系人请重新输入这里的assert函数是断言的意思可以参考我第一篇博客,goto是跳转操作我们进入goto语句时我们会跳到goto语句的条件位置;我们需要定义结构体类型可以用一种文艺点的说法就是为我们的数据储存提供空间构造框架,当这个空间被开辟好了之后我们就可以向这个空间增加与改变我们的数据,先声明它再去使用它。首先我们先创建一个菜单。

2023-04-12 20:42:00 101 2

原创 字符函数和字符串函数的模拟实现

总而言之strlen是通过\0字符来判断字符串是否统计结束的;通过上面的代码我们可以知道这个函数是用来比较这两个函数是否相同的如果相同就会返回0,如果前面的数组大于后面的数组则返回大于0的数反之则返回小于0的数,这里的大于小于是指我们从第一个元素开始两个数组的每个两个对应元素相比较,比较这两个字符的ascii码值大小;这个函数是将参数中后面的数组复制给前面的数组,我们需要注意前面的数组的大小一点要大于后面的数组,否则数组会放不下,我们再把后面数组的值一个一个赋值给前面的数组,直到后面的数组遇到了\0;

2023-04-10 22:08:01 38

原创 数据的存储

我们可以看到它的数据是01 00 00 00排列的;不可以说他们相等因为我们不确定我们机器显示的相等是否精确我们小数点后精度是通过不断向后找数来增加它的精度的就比如说0.14它二进制0.01表示为0.25大于0.14我们继续往后找数找到0.001它的大小是1*2^-3为0.125它小于0.14但是我们还需要往后找0.14-0.125=0.015的差量加上去我们就需要不断的往后找数不断的增加我们的精度但是我们的m位在32位机器中只有23个bit位所以可能无法完全精确,所以就导致我们机器出现了精度误差。

2023-03-31 21:56:50 49

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除