- 博客(16)
- 收藏
- 关注
原创 vector常见接口及其模拟实现
1. vector是表示可变大小数组的序列容器。2. 和数组一样,vector也采用连续存储空间来存储元素。这意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。3. vector使用动态分配数组来存储它的元素。首先分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是 一个相对代价高的任务。
2025-11-02 22:29:24
774
原创 AVL树及底层模拟实现和四种旋转方式的模拟实现
总结:旋转后,要更新每个结点的成员。而二叉搜索树的插入方式是比当前结点大的插在当前节点的右子树上,比当前节点小的插在当前节点的左子树上,并且插入的元素的结点在插入后一定是。插入结点前,AVL树是平衡的,当插入30的左子树时,此时以60为根的二叉树不平衡,因此要旋转让该树平衡。插入结点前,AVL树是平衡的,当插入60的右子树时,此时以30为根的二叉树不平衡,因此要旋转让该树平衡。的操作,性能非常低下,比如:插入时要维护其绝对平衡,旋转的次数比较多,更差的是在删除时, 有可能一直要让旋转持续到根的位置。
2025-11-02 16:09:15
795
原创 红黑树及模拟底层实现
因为每个结点要增加一个存储位,用来表示该节点是红色还是黑色,所以这里用枚举表示。注意:这里定义结点时,要将结点颜色默认为红色。因为默认节点颜色为红色,此时结点插入树中时,最多违反性质3,调整成本低。若默认结点颜色为黑色,此时结点插入树中时,违反了性质4,此时调整时意味着其它路径的黑色结点数量也要调整,成本太高,因此要将默认结点颜色设为红色。
2025-10-31 21:43:43
1005
原创 string类常用接口及底层模拟实现
1. 首先要了解一个情况,为什么要引入string类。因为C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可 能还会越界访问。另外,在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数。2. string类是什么。1. string是表示字符串的字符串类。
2025-09-06 17:12:00
660
原创 类和对象中-构造函数、析构函数和拷贝构造函数
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。注意:构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。默认构造函数只能有一个。析构函数:与构造函数功能相反,析构函数是完成对对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。并且析构函数是特殊的成员函数。
2025-09-05 19:45:02
983
原创 快速排序的递归实现和非递归实现
找比基准值小的值,找到后停在此位置,然后指向首位置的left开始向右走,找到比基准值大的值,找到后停在此位置,然后将此时left和right分别指向的值进行交换,再继续刚才的找法。进入循环,然后判断cur位置的值是否小于基准值,若小于,再判断prev+1后的位置是否与此时cur不在同一位置,若是,则交换此时prev和cur位置的值。首先定义变量prev,并用其保存left的值,再定义变量cur,cur保存left+1的值,并定义基准值的位置key是left的位置。因此使用非递归形式进行排序是必要的。
2025-07-27 23:34:38
1888
原创 栈、队列、顺序表、链表、二叉树这些都是存储数据的方式,跟数据结构有什么关系
数据结构是数据的逻辑模型,定义了元素之间的关系和操作。存储方式是数据结构的物理实现(如数组、指针),直接影响操作效率。存储方式是数据结构的“工具”,而数据结构是解决问题的“蓝图”。选择哪种工具(如数组或链表),取决于你对效率、灵活性和应用场景的权衡。
2025-07-21 09:41:51
448
原创 栈和顺序表、由链表构成的队列和链表的异同
顺序表:是一种线性表,元素在内存中连续存储,逻辑上呈线性排列,允许在任意位置(表头、表中、表尾)进行插入、删除和访问操作。栈:是一种特殊的线性表,遵循“后进先出(LIFO,Last In First Out)”原则,只能在表的一端(称为“栈顶”)进行插入(入栈)和删除(出栈)操作,另一端(栈底)固定不动。// 单向链表结点int val;// 数据域(值)// 指针域(指向下一个结点)} ListNode;// 双向链表结点int val;// 前驱指针// 后继指针。
2025-07-20 22:29:24
498
原创 栈和队列的创建
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循先进后出原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据也在栈顶栈顶的本质:最后插入的元素位置,随操作动态变化。最后入栈的元素最先出栈栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。栈的结构有两种,一种是静态栈,但不具备实用性,主要使用可支持动态增长的栈。实现动态栈时使
2025-07-18 23:32:29
603
原创 二叉树的链式结构及实现
首先访问根结点,然后再访问左子树,若左子树本身就作为一个结点,则访问左子树后无法立刻访问右子树,要先访问左子树作为结点的左子树,若此时的左子树是空,则返回空,再访问右子树,若右子树为空,则返回空,这个过程结束后才能访问根节点的右子树,访问右子树也跟左子树一样逐级递归下去。先访问左子树,若左子树本身作为结点时,就要先访问其作为结点时的左子树,若此时的左子树为空则返回空,再访问其作为结点时的右子树,若右子树为空则返回空,此时代表左子树访问完了,再访问根结点,然后访问右子树,右子树访问再逐级递归下去。
2025-07-17 16:09:45
973
原创 二叉树的顺序结构及实现
初始堆数组(大顶堆):[70, 60, 40, 30, 10] 插入后数组:[70, 60, 40, 30, 10, 80]比较:a[parent] = 70 < a[child] = 80 操作:交换 70 和 80 交换后数组:[80, 60, 70, 30, 10, 40]3 < 5 → 交换,最终数组为 [7, 5, 4, 3, 1, 2]。2 < 4 → 交换,数组变为 [3, 5, 4, 7, 1, 2]。较大子节点:60(左孩子)。
2025-07-17 10:30:36
1836
原创 链表的构成和常见问题
链表的销毁是由调用者手动删除的,即释放所有节点的内存,并且必须将,避免它成为也就是说必须使用二级指针来将外部头指针置空。这里销毁时如果使用一级指针也能将所有结点的内存释放,但是外部头指针的值无法置空,会造成野指针的现象。这种方式是错误的。这里有一个问题就是为什么要使用二级指针,因为要想改变int的值就必须在主函数中调用时传入int的地址即指针,要改变int*的值就必须传入指针变量int*的地址即二级指针,同理,要改变结构体指针phead的值就必须传入。
2025-07-11 11:10:04
623
原创 指针数组和数组指针的定义与用法
之前学过整型数组是存放整型的数组,字符数组是存放字符的数组,由类比可知,指针数组就是存放指针的数组。同理,指针数组的类型也是数组名去掉后的剩余部分。定义方式如下://type是存放指针指向的对象的类型,ptr是数组名,size是数组的大小。表示ptr 是一个包含 size 个指向type类型的指针的数组。如以下例子:表示ptr是一个数组,其存放了5个指针,每个指针指向的类型均是int类型。其存放形式如下图:之前学过整型指针变量存放的是整型变量的地址,指针指向整型数据;
2024-10-17 11:04:33
1354
原创 字符数组、字符串指针和字符指针的定义与区别
所谓的字符数组即是存放字符或字符串的数组,通常有两种形式。如:上述第一种定义方式是定义一个字符数组,其存放的元素是字符;第二种也是字符数组但也可以称为字符串数组,其数组的大小会有编译器自动计算字符串的长度,之所以有第二种定义方式是因为字符串在C语言中默认是以数组的形式存储的。需要注意的是:不可定义一个字符数组用来存放字符串,只有通过第二种方式定义或采用字符指针的形式定义。如:char str[2] = { "hello","world" };这种方式是错误的。
2024-10-15 09:37:57
538
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅