自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 C++ 红黑树

这里写目录标题一,红黑树的概念二,红黑树的性质三, 红黑树的节点的定义四,红黑树的插入五, 红黑树删除六, 红黑树验证七,红黑树与AVL树的比较一,红黑树的概念红黑树,是一种二叉搜索树,在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。二,红黑树的性质每个结点不是红色就是黑色 。根节点是黑色的 。如果一个节点是红色的,则它的两个孩子结点是黑色的 。(不

2022-11-08 16:01:48 190 1

原创 C++AVL树

这里写目录标题一,什么是AVL树二, AVL树的性质三,AVL树的模拟实现3.1 AVL树节点定义3.2 Insert3.3 平衡因子更新规则3.4 AVL的旋转四, 验证AVL树五,AVL树的性能一,什么是AVL树当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1,这样的二叉搜索树叫做AVL树。二, AVL树的性质1,它的左右子树都是AVL树。2,任意一个子树的左右子树高度之差(平衡因子)不超过1.这里的平衡因子是右子树的高度-左子树的高度。三,AVL树

2022-11-08 15:56:46 361

原创 map和set

在set中插入元素x,实际插入的是构成的键值对,如果插入成功,返回pair,如果插入失败,说明x在set中已经存在,返回pair。第二个参数:缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的。

2022-11-05 15:11:17 232

原创 C++继承

1,构造函数私有化(实例化对象时会报错)(C++98)2,C++11 新增了一个关键字 final1,C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。2. 多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。(学生是人,玫瑰花是植物)

2022-10-16 16:36:58 742

原创 Linux 进程程序替换

(2)我们之前的理解加载新程序之前,父子进程的代码和数据的关系是代码共享,数据写时拷贝。fork()之后,父子各自执行父进程代码的一部分,那如果子进程就想执行一个全新的程序,相当于子进程想要有自己的代码,那么该怎么做呢?答案是需要的,因为要保证进程的独立性,所以在进程替换这样的场景下,父子进程在代码和数据上就彻底分开了,虽然曾经并不冲突。程序替换,是通过特定的接口,加载磁盘上一个全新的程序(代码和数据),加载到调用进程的地址空间中。我们想让父进程聚焦在读取数据,解析数据,指派进程执行代码的功能。

2022-10-04 15:35:14 273

原创 STL queue,stack,priority_queue的模拟实现

因为deque可以任意位置插入删除,可以随机访问,是list和vector的结合体,对于头尾的插入删除,queue很适合,对于中间插入删除多用list,对于随机访问多用vector。3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作:empty,back,push_back,pop_back。2容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出。

2022-09-28 23:05:37 130

原创 STL list的模拟实现(反向迭代器)

list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。不能,list不是一个连续的物理空间,但是我们可以用c++的特性,用类去封装迭代器,用运算符重载改变对象用运算符的行为。it是指向第一个节点的指针,解引用是第一个节点,++能到下一个位置吗?首先 ,我们定义节点`接下来,我们定义链表。我们来看下面的代码。

2022-09-28 20:43:50 625

原创 Linux 进程地址空间

每个进程都要有地址空间,操作系统要对每一个地址空间做管理(先描述,再组织)内核中的地址空间,本质上是一种数据结构,将来一定要和一个特定的进程关联起来。地址空间是一种内核数据结构,他里面至少要有各个区域的划分。在Linux内核中,进程虚拟地址空间叫做struct mm_struct{}。我们一定会有一个结构task_struct进程控制块用指针指向mm_struct,虚拟地址到物理地址的映射关系,操作系统为我们维护了一个表结构,叫做页表,那么我们就能根据映射关系,找到每个区域各自的数据。

2022-09-28 18:34:54 427

原创 STL vector的模拟实现

就不会走vector(size_t n, const T& value = T())这个构造方法,最终选择的是:vector(InputIterator first, InputIterator last), 因为编译器觉得区间构造两个参数类型一致,因此编译器就会将InputIterator实例化为int,但是10和5根本不是一个区间,编译时就报错了,故需要增加vector(int n, const T& value = T())方法。resize()的功能,如果n小于当前size,则删除数据到n。

2022-09-21 20:25:18 140

原创 类与对象1

1,声明和定义全部放在类体中,成员函数如果在类中定义,编译器可能会将其当做内联函数处理。(5)如果类中没有显式定义构造函数,则c++编译器会自动生成一个无参的默认构造函数。3,protected和private修饰的成员在类外不能直接被访问。2,类声明放在.h文件中,成员函数定义放在.cpp文件中。1,在c++中,结构体不仅可以定义变量,也可以定义函数。1,构造函数是特殊的成员函数,任务是初始化对象。2,代码只保存一份,在对象中保存存放代码的地址。3,只保存成员变量,成员函数存放在公共的代码段。...

2022-08-12 10:06:57 216

原创 C++入门

特点:C++允许在同一个作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同。1,概念:引用不是新定义了一个变量,而是给已存在变量取别名。编译器不会额外开辟空间。出了函数作用域,返回对象就销毁了,那么一定不能用引用返回,要用传值返回。2.1,概念:缺省参数是声明或定义函数时为函数的参数指定一个缺省值。(3)访问实体方式不同,指针需要显式解引用,引用编译器自己处理。(1)引用概念上定义一个变量的别名,指针存储一个变量地址。(3)引用一旦引用一个实体,再不能引用其他实体。.

2022-08-08 11:31:15 220

原创 20.有效的括号

有效的括号

2022-05-31 21:49:48 87

原创 141.142.环形链表

环形链表 代码为代码为

2022-05-31 21:01:49 104

原创 86.分隔链表

思路:可以先将链表分隔成两个链表,一个链表为小于x的链表,一个链表为大于等于x的链表,然后将他们合并起来,就完成本题。(1)设置两个哨兵节点dummy1和dummy2分别来链接小于x的链表和大于等于x的链表。(2)遍历原链表,将小的放在dummy1后,将大的放在dummy2后。(3)分隔完成之后,将cur1->next=dummy2->next,完成链接,最后要将cur2->next=NULL避免成环。代码为struct ListNode* p...

2022-05-30 22:29:29 128

原创 堆的基本操作详解

堆的性质1,堆中某节点的值总是不大于或不小于其父节点的值。2,堆是一颗完全二叉树。1,堆分为两种,大根堆和小根堆。2,我们用数组来存储堆,所以我们想象出来的是一颗完全二叉树,实际上操纵的是数组。如图:3,现在我们来实现堆的基本操作。(1)首先,我们来创建一个结构体来表示堆。typedef struct Heap{ HPDataType* _a;//使用动态的数组,方便扩容。 int _size;//堆的有效数字的个数 int _capacity..

2022-05-30 22:18:25 954

原创 138.复制带随机指针的链表

思路:(1)将每个节点拷贝一份分别链接在原链表的后面。 (2)拷贝节点的random等于原节点的random的next。(3)拆分链表。拆成原链表和拷贝链表即可完成。代码为struct Node* copyRandomList(struct Node* head) { if(head==NULL) return NULL; //第一步 拷贝节点链接到原节点的后面 struct Node* cur=head; w...

2022-05-30 21:15:11 88

原创 160.相交链表

思路:(1)先找出链表A和B中长的那一个。 (2)算出链表A和B的差距x。 (3)长的先走 x步。 (4)然后一起向后走。 (5)相等即为相交节点。struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { struct ListNode *curA=headA; str...

2022-05-30 20:17:19 75

原创 234.回文链表

思路:(1)可以将链表分为两半,list1和list2。如何分成两半,就用快慢指针找到中间节点。 (2) 将list2逆置。 (3)将list1和list2进行比较,如果相等,就是回文链表,如果不相等,就不是。 如果是奇数个,就比较到list1完就停止。struct ListNode* reverse(struct ListNode* head) //逆置{ struct ListNode*cur=h...

2022-05-30 19:58:07 93

原创 876链表的中间节点

采用双指针(1)设置slow和fast两个指针,slow一次走一步,fast一次走两步。(2)如果节点个数是奇数,那么直到fast->next为空时,slow指向中间节点。(2)如果节点个数是偶数,那么直到fast为空时,slow指向中间节点。代码为struct ListNode* middleNode(struct ListNode* head){ if(head==NULL) return NULL;struct ListNode*...

2022-05-29 16:08:01 85

原创 83删除排序链表的重复元素

使用双指针。(1) 设置两个指针fast和slow,slow指向前一个节点,fast指向后一个节点。(2)如果slow指向的值等于fast指向的值,slow不变,fast=fast->next. (3)如果slow指向的值不等于fast指向的值,要删除重复的节点,就将slow->next=fast,slow和fast后移。(4)重复(2)(3)直到fast为空结束。注意:如果最后几位重复,那么需要将slow->next=NULL达到删除的目的。str...

2022-05-29 15:23:48 96

原创 21 合并两个有序链表

1,采用双指针。 使用带哨兵的头结点dummy,将合并之后的新链表链接在后面。(1)设置一个cur指针指向合并后链表的尾结点。(2)将list1和list2指向的值进行比较。(3)如果list1的值<=list2的值,就将l1的节点链在哨兵节点的后面,然后list1=list1->next,cur=cur->next;(4)如果l1的值>l2的值,就将l2的节点链在哨兵节点的后面,然后list2=list2->next,cur=cur->...

2022-05-29 14:41:19 202

原创 19.删除链表倒数第k个节点

1,用带哨兵位的头结点。struct ListNode* removeNthFromEnd(struct ListNode* head, int n){ if(head==NULL) return NULL;struct ListNode* newnode=(struct ListNode*)malloc(sizeof(struct ListNode));//创建一个带哨兵位的头。newnode->next=head;struct ListNode* fa...

2022-05-29 13:31:42 275

原创 206.反转链表

(1)使用双指针(1)一开始定义两个指针cur和prev,cur指向第一个节点,prev指向空。(2)然后将cur->next指向prev ,实现第一次反转,但是如果直接改cur->next,那么下一个节点就找不到了,为了方便起见,再定义一个指针next,保存cur的下一个节点。(3)然后不断地使cur->next=prev,然后向后遍历。(4)可见,当cur为空时就结束。代码为:struct ListNode* reverse...

2022-05-13 22:12:55 187

原创 栈的基本操作

栈,一种特殊的线性表,只允许在固定的 一端进行插入和删除操作,栈中的数据遵循后进先出原则。可以用数组和链表来表示栈。(1)如果使用链式栈,如果用尾作栈顶,尾插尾删,要设计成双向链表,否则删除数据效率低。如果用头作栈顶,头插头删,可以设计成单链表。(2)综合这两种,如果非要选一种,数组栈稍微好一点。1,定义栈typedef struct Stack { STDatatype* a; //使用动态的数组 int top; //栈顶元素下一个元素的下标 int cap...

2022-05-13 20:48:55 164

原创 c语言操作符(1)

c语言操作符

2022-04-18 17:09:03 370

空空如也

空空如也

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

TA关注的人

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