- 博客(35)
- 收藏
- 关注
原创 Linux进程控制--进程创建 | 进程终止 | 进程等待 | 进程替换
创建子进程的目的:1、执行父进程的部分代码;(我们前面的文章中所写的代码就属于这种情况)2、执行其他程序的代码;(不要父进程的代码和数据,所以要学习进程替换)进程替换是为了让子进程能够执行其他程序的代码,进程替换就是以写时拷贝的策略,让第三方进程的代码和数据替换到父进程的代码和数据,并给子进程使用。因为进程间具有独立性,所以不会影响父进程。把其他程序的代码放到内存中让子进程看到,以前子进程看到的是父进程的代码,现在有新的代码来了,此时也要对代码进行写时拷贝。
2025-03-26 20:25:58
857
原创 进程地址空间
我们在语言的学习过程中,涉及到C/C++内存布局这个概念。上图表示的是内存吗?我们曾经学习过的C/C++内存布局,严格来说是错误的。从现在开始我们将程序地址空间称为C/C++进程地址空间。为什么要故意说错呢?其实是为了方便理解,如果在刚开始学习C/C++进程地址空间时,谈进程、地址、空间,很容易误导大家。也就是说要真正理解C/C++的空间布局,光学习语言是不够的,还需要学习系统以及进程和内存之间的关系。进程地址空间既然不是内存,那么栈、堆等这些空间的数据存储在哪?
2025-02-25 21:50:10
933
原创 进程的介绍--进程状态/切换
操作系统对每一个进程进行了描述,这就有了一个一个的PCB结构体,Linux中的PCB就是task_struct(在其他操作系统中的PCB不一定叫task_struct),task_struct是一个内核结构体(即操作系统给我们提供的、用来描述进程的结构体),这个结构体中有next、prev指针,可以用双向链表将进程链接起来,task_struct结构体的部分指针也可以指向进程的代码和数据。
2025-02-21 23:34:21
632
原创 【Linux环境变量与命令行参数】常见环境变量 | 环境变量的全局属性 | 命令行参数
本文中主要介绍PATH、HOME、SHELL、HISTSIZE这4个环境变量,其中详细介绍PATH。并理解环境变量的全局属性--环境变量可以被子进程继承,这里要注意和C++中的继承进行区分。其次,介绍命令行参数--mian函数的参数。Linux的命令行就是bash,bash是可以定义变量的。如下图所示:在命令行中写下指令myval=100后,shell读取到指令,就会在内存中申请一块空间,并把该变量以字符串"myval=100"的形式存放进去,最后在shell内部另外生成一个指针指向该字符串。
2025-01-21 23:37:23
977
原创 哈希表的完善及unordered_map/unordered_set封装
在实际使用中,往往需要以字符串作为存储依据(键值),比如姓名与快递信息、商品名称与价格、中文单词与英文释义等。而在上一篇文章中,我们实现的哈希表只考虑了整型的存储情况,即直接用key%capacity计算哈希值,如果把整型换成字符串是无法进行计算的。如下图所示。为了解决这个问题,我们可用将获取key值单独封装为一个仿函数,再利用模板特化,使其既能支持整型也能支持字符串。
2024-12-09 21:13:57
792
原创 哈希及其模拟实现
数据和状态。//定义结构体存储数据T _data;哈希桶中需要维护一个单链表,因此需要一个_next指针指向下一个节点。T _data;{}因为引入了单链表,所以哈希桶中表的存储类型也变成了节点指针。public://...private://记录表中存储的数据的个数。
2024-12-03 22:58:54
950
原创 红黑树模拟实现STL中的map与set
/节点的左孩子//节点的右孩子//节点的父亲节点(红黑树需要旋转,为了实现简单给出该字段)//节点的值域//节点的颜色, _kv(kv){}这里将红黑树节点中的K-V键值对pair<K,V>修改成类型T,T类型的_data是pair键值对还是单个的值,视情况而定。如果是map的需求,那么就是pair;如果是set的需求,那么就是一个K。//节点的左孩子//节点的右孩子//节点的父亲节点(红黑树需要旋转,为了实现简单给出该字段)T _data;//节点的值域//节点的颜色{}
2024-11-23 16:56:36
945
原创 RBTree--红黑树
BLACK,RED,//节点的左孩子//节点的右孩子//节点的父亲节点(红黑树需要旋转,为了实现简单给出该字段)//节点的值域//节点的颜色,_kv(kv),_col(RED){}
2024-11-17 22:32:15
1172
原创 AVLTree
由于要实现AVL树的增删查改,所以要定义AVL树的节点,就需要定义parent,否则插入节点时,不知道要链接到树中哪个节点下面。//指向左子树//指向右子树//指向父亲节点//用pair存储一对值int _bf;//平衡因子,_kv(kv),_bf(0){}
2024-11-04 22:46:06
992
2
原创 STL序列式容器之string的基本用法及实现
在使用string类时,必须包含头文件以及using namespace std;接下来我们看看string可以看到:string类是被basic_string用char实例化后得到的一个具体的类的别名。1.string是表示字符串的字符串类;2.该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作;3.string在底层实际是:basic_string模板类的别名,typedef basic_string string;
2024-10-16 21:51:05
892
原创 二叉搜索树(Binary Search Tree)
它或者是一棵,或者是具有以下性质的二叉树:1. 非空左子树的所有键值小于其根节点的键值;2. 非空右子树的所有键值大于其根节点的键值;3. 左右子树也分别为二叉搜索树。二叉搜索树一般不支持key值冗余(不允许有重复的key值);二叉搜索树的性质使搜索时非常方便高效,最多搜索高度次O(logN)(二叉树退化为O(N),需要二叉搜索树平衡,使用AVL树或者红黑树);二叉搜索树的中序遍历能够对key进行排序。
2024-09-18 00:02:18
758
原创 二叉树的前中后序遍历(非递归迭代实现)
前序遍历的顺序是根-左子树-右子树,所以首先从根节点开始,顺着访问左子树:1、2、4。此时,还剩下节点1、节点2、节点3的右子树没有访问。后面倒着访问节点1、2、4的右子树就行了。所以非递归的前序遍历是这样处理的:把一棵二叉树分为两个部分:1、左路节点;2、左路节点的右子树。如下图所示:对于每一棵右子树,也是同样划分为这两个部分进行处理。如何倒着取处理左路节点的右子树?我们可以借助栈来处理左路节点的右子树。以上图中的树为例,从根节点1开始,依次访问。
2024-09-16 12:50:29
1106
原创 STL容器适配器之priority_queue的基本用法及模拟实现
heap并不归属于STL容器组件,priority_queue允许用户以任何次序将任何元素推入容器中,但取出时一定是从优先权最高(也就是数值最高)的元素开始取。大根堆正是具有这样的特性,适合作为priority_queue底层机制。关于完全二叉树以及堆的详细介绍可以参考二叉树详解堆的介绍这两篇文章。堆(heap)是一种特殊的额完全二叉树,它满足下面的性质:(1)堆是一个完全二叉树,这意味着除了最后一层外,每一层都是完全填满的,而最后一层的节点则京可能的集中在左边。(2)
2024-09-09 23:36:53
994
原创 STL容器适配器之stack、queue的基本用法及模拟实现
本文中实现的MyQueue类是一个泛型队列,使用模板参数T来指定队列元素的类型,而模板参数Container来指定底层容器的类型,它默认为std::deque<T>,但也可以被替换为其他类型如std::list或std::vector。基于容器C++STL中的std::stack是一个容器适配器,它不是一个独立的数据结构,而是构建在其他容器之上的。默认情况下,std::stack使用std::deque作为其底层容器,但是也可以选择使用std::vector、std::list等其他容器来作为底层支持。
2024-09-04 23:03:04
667
原创 关于堆的介绍
int _size;}Heap;(1)Top-K问题的定义求出一组数据中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。比如:专业前10名、世界500强、富豪榜等。我们以求n个数据中前K个最大的元素为例进行说明:(假设n=10000、K=10)。(2)解决Top-K问题的思路①排序法(不推荐使用)对于Top-K问题,能想到的最简单直接的方法就是排序,我们可以把这个10000个数据排成降序,然后逐个取前10个数就是最大的10个数。
2024-08-15 22:48:34
1074
原创 STL序列式容器之list的使用及实现
std::list 和 std::vector 是两种不同的数据结构,std::vector 是基于数组的动态数组,而 std::list 是基于双向链表的数据结构。list适用于需要在序列中频繁执行插入和删除操作的场景。
2024-08-03 22:24:57
1082
原创 数据结构之无头单向非循环链表
我们是使用一个结构来定义无头单向非循环链表的基本结构,如下所示,该结构体包括数据域和指针域两个部分。//链表的结点}ListNode;
2024-07-24 21:52:54
483
原创 vector的模拟实现
MyVector 类包含了构造函数、析构函数、拷贝构造函数、拷贝赋值操作符、添加元素、获取元素个数、获取容量、访问元素的功能。
2024-07-15 22:00:00
723
原创 STL库序列式容器之vector的工作原理及基本用法
是一个动态数组,它在内存中以连续的块存储元素。与静态数组相比允许在运行时动态调整大小,而无需手动管理内存。
2024-07-10 21:50:59
928
原创 C++中产生临时对象的情况及其解决方案
C++中三种常见的临时对象创建的情况:(1)以值传递的方式给函数传参;(2)类型转换;(3)函数需要返回对象时。
2024-05-27 23:30:37
1578
原创 数据结构之顺序表
在介绍顺序表之前,我们先介绍线性表。线性表 ( linear list ) 是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。也就是说顺序表是线性表顺序存储结构中的一种。
2024-04-27 13:57:14
1392
1
原创 只出现一次的数字(三种情况)
在介绍只出现一次的数字之前,先介绍一下消失的数字这个题目,数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?[3,0,1]28思路:该题要求在O(n)时间内完成,使用遍历方法的时间复杂度是O(n^2),不符合题目要求。假设数组int nums[]={0,1,2,3,4,5,6,7,9},中间缺了数字8,先使用num=0与数组中所有元素做异或运算,然后将运算的结果再与[0,N]中的元素挨个做异或运算,得到的结果就是那个消失的数字。
2024-04-01 22:28:06
833
1
原创 名字的作用域
名字sum定义于main函数所限定的作用域之内,从声明sum开始直到main函数结束为止都可以访问它,但是出了main函数所在的块就无法访问了,因此说变量sum拥有。无论在程序的什么位置,使用到的每个名字都会指向一个特定的实体:变量、函数、类型等。然而,同一个名字如果出现在程序的不同位置,也可能指向的是不同的实体。作用域中一旦声明了某个名字,它所嵌套着的所有作用域中都能访问该名字。同一个名字在不同的作用域中可能指向不同的实体。名字的有效区域始于名字的声明语句,以声明语句所在的作用域末端为结束。
2024-01-21 11:58:39
438
1
原创 序列中删除指定数字
有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变。数据范围:序列长度和序列中的值都满足1≤n≤50。输入描述:第一行输入一个整数(0<N≤50)。第二行输入N个整数,输入用空格分隔的N个整数。第三行输入想要进行删除的一个整数。输出描述:输出为一行,删除指定数字之后的序列。
2023-11-26 21:19:27
84
1
原创 冒泡排序(上)
改代码执行的结果依然为:9 8 7 6 5 4 3 2 1 0。冒泡排序的核心思想是两个相邻元素进行比较。冒泡排序的一个典型错误。
2023-11-19 21:47:27
65
1
原创 计算一个数的每位之和(递归实现)
写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和。例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19。该题要求使用递归函数实现,思路。
2023-11-18 22:19:17
79
1
原创 使用递归函数实现字符串反转
编写一个函数reverse(char * string)(递归实现)实现:将参数字符串中的字符反向排列,不是逆序打印。要求:不能使用c函数库中的字符串操作函数。
2023-11-18 21:22:10
207
1
原创 【无标题】
则时间复杂度为O(N2),即取阶数最高的那项。如果N2前面有系数,则系数也去掉,如F(N)=2N2+2*N+10,则时间复杂度为O(N2)。算法的时间复杂度是一个函数,算法的时间复杂度算的不是时间,算的是程序执行的大概次数。随着N的增大,对F(N)的值影响最大的N2,即阶数最高的那项对结果的影响最大。大O符号(Big O notation ):是用于描述函数渐进行为的数学符号。Func1执行的基本操作次数:F(N)=N2+2*N+10;请计算一下Func1基本操作执行了多少次?
2023-11-13 20:58:43
44
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人