- 博客(50)
- 问答 (1)
- 收藏
- 关注
原创 Qt QWidget控件
widget翻译而来就是小控件,小部件。控件是指可以操纵的部件,下图Qt页面中的按钮, 列表视图, 树形视图, 单⾏输⼊框, 多⾏输⼊框, 滚动条, 下拉框等, 都可以称为 "控件".QWidget是所有窗口部件的基类,例如对话框类、主窗体类,以及其他诸如按钮、编辑框、标签等都由QWidget派生得到,所以QWidget的所有的方法往往都可以在其他子类当中使用二、QWidget核心属性属性作用enable设置控件是否可用,true表示可用,false表示不可用geometry。
2024-10-03 19:17:29 888
原创 set和map
map和set与以往容器不同的是它是关联式容器,而vector、list、deque是序列式容器,序列式容器是以线性排列的方式来存储数据的,元素在容器中的位置与插入顺序有关,其实底层是顺序表和链表。而map和set底层是二叉搜索树,更深入点讲是红黑树,元素在容器中的位置与插入顺序无关,因为有可能经过红黑树旋转改变原先的位置。与别的容器不同的是set会自动排序和去重set值得注意的第二点是set不支持修改,只能删后重新插入。因为底层是红黑色,直接进行修改会直接破坏红黑树和二叉搜索树的规则。
2024-09-26 22:04:09 942
原创 红黑树构建模拟实现
红黑树也是一种二叉搜索树,在二叉搜索树的基础上它也定义了一些规则来使平衡树相对平衡。AVL树是通过左右高度差(平衡因子)来控制搜索树的平衡,构建出来是非常接近完全二叉树和满二叉树的树。而红黑树是一种相对平衡,最长路径不超过最短路径的两倍就可以了,红黑树在每个结点上增加一个存储位表示节点的颜色,可以是红色也可以是黑色,通过对任何一条从根到叶子的路径上各个节点着色方式的限制,红黑色树确保没有一条路径会比其他路径长出两倍,从而达到相对平衡。
2024-09-19 14:23:26 612
原创 Qt构建JSON及解析JSON
一般来讲C++类和对象在java中是无法直接直接使用的,因为压根就不是一个规则。但是他们在内存中都是二进制表示的,所以把C++的类和对象转成二进制再按照java的规则解析这段二进制代码就可以做到C++描述的东西在java中复现了。
2024-09-17 23:14:09 1389 1
原创 AVL树调整平衡及旋转详解
AVl树算是二叉搜索树的一种补充版,普通的二叉搜索树在最坏的情况下可以达到O(n)的时间复杂度,也就是歪脖子树。为了解决二叉搜索树的歪脖子现象,需要对插入的节点进行调整以达到相对平衡,这种经过调整的二叉搜索树叫二叉平衡树,而AVl树是平衡树的一种。AVl树总的来说就是所有节点的左右子树高度差不超过1所以AVL树有两个性质,第一必须满足二叉搜索树的规则,也就是所有节点的右边子树节点值都比根节点值大,左边节点值都比根节点值小。第二所以节点左右子树高度差(通常称为平衡因子)不超过1。
2024-09-04 18:50:23 954
原创 二叉搜索树
二叉搜索树也叫二叉排序树,搜索二叉树,与普通的二叉树相比二叉搜索树满足所有节点右孩子值都比根节点值大,左孩子值都比根节点值小。下图中第一个二叉树5是10的右孩子但是值比10小,所以不满足二叉搜索树的规则下图是一个完整的二叉搜索树,如果使用中序遍历的话会发现正好是有序的1,3,4,6,7,8,10,13,14,这也就是为什么二叉搜索树也叫做二叉排序树。
2024-08-24 20:09:41 745
原创 stl容器适配器 stack与queue,priority_queue
值得注意的是模拟的进队列函数直接进第一个栈就行,出队列和取栈顶元素把第一个栈的元素倒着插入第二个栈时要考虑第二栈是否为空,只有为空的时候才能挪动第一个栈的数据。库里的实现要复杂一点(见下图),cur是当前节点位置,first是内存块的开始位置,last是末尾数据的下一位,当遍历访问的时候cur从first开始挨个往后挪动,当cur等于last时说明这个内存块访问完了,中控那里的node节点位置++,找到下一个内存块的地址,然后cur重新赋值为新内存块first地址,从头开始往后找。
2024-08-21 14:42:33 1013 1
原创 list使用及底层模拟实现
/指向存放字符串的空间,size_t _size;传一个const T过去不就行了,这样写其实是会报错的,这是因为迭代器的构造函数 iteratorlist(Node<T> *node):_node(node)这时候这个T类型实际上是const T,但是list当中begin和end传过来构造的节点可是T类型,举个例子list当中要求生成int类型的迭代器,可是迭代器当中是const int,这种没有什么权限缩小可以兼容使用,模版推演是严格遵守规则的(一点不同都生成不了),所以迭代器会生成失败。
2024-08-14 00:29:28 992
原创 vector底层模拟实现
具体的挪动数据操作,end必须在finish-1上,不能在finish上,finish位置上是无效数据(有可能是随机值), 即使空间容量足够也不能挪动这个位置上的数据。finish此时还指向旧空间,start已经确定了,finish是不能直接一步到位指向有效字符的下一个的,所以用上了之前保存的oldsize,oldsize是原来的有效字符个数,start加上start就是finish的位置,因为我的有效字符size压根就没改变,在新空间里finish和start也会保持这种相对位置关系。
2024-08-06 23:15:23 823 2
原创 stl容器 vector的基本操作
vector是vector类模版类型,尖括号里的类型是指生成什么类型的vector的类,实质上vector可以看做一个数组,vector实质上就是生成了一个存int类型的数组,而tamp是这个数组的名字。这样默认构造是默认构造了一个空的vector数组,类型不是int,而是vector因为是尖括号里是模板所以也可以使用别的类型来构造函数,比如string,这样生成的就是string类型的数组了。
2024-08-04 12:00:00 791
原创 C++多态
多态是在不同继承关系的类对象,去调用同一对象,产生了不同的行为。比如Student继承了person。person对象买票全价,Student对象买票半价那么在继承中要构成多态还有两个条件:1.必须通过基类的指针或者引用调用虚函数2.被调用的函数必须是虚函数(被virtual修饰的函数),且派生类必须对基类的虚函数进行重写2.2虚函数的重写。
2024-07-28 21:35:24 825
原创 继承和派生
继承机制是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类基础上进行扩展,增加功能,产生新类,称为派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知的过程。以前接触的复用都是函数复用,比如重载,而继承是类设计层次的复用。继承的类与被继承的类也被叫做子类与父类或者派生类与基类,继承这一概念用子类与父类来通俗一点来讲的话就是儿子继承父亲的财产,儿子可以用父亲的东西比如公司,但是儿子在继承之前也许创业开了新公司,这个新公司与父亲没有什么关系。
2024-07-20 16:41:02 985 1
原创 string类模拟实现
str是一个指向存放字符串空间的指针,new出来的空间是用来存传过来字符串的,new的空间+1是为了存\0,库里面capacity()和size()是不计算\0大小的,虽然它不计算,但是还是要开空间存它的。起始迭代器begin和末尾迭代器end就直接用函数来表示,起始迭代器指向字符串的第一个字符位置,末尾迭代器指向最后一个字符的后一个位置(也可以看做指向\0),_size构造函数构造的时候是没有把\0给算进去的,实际上是有效字符个数,但是最后一个有效字符数组里面下标其实是_size-1。
2024-05-24 23:23:12 912
原创 函数模板与类模板初阶
如果要写一个交换函数,不同类型的话调用不同的交换函数,如果使用重载的话只能解决函数名相同但是会根据参数类型调用不同的函数。即使这样也依旧要写很多不同类型的swap交换函数函数重载的交换函数仔细观察会发现除了类型不同其他的函数结构什么的都一样,都是定义中间变量,然后用它作为过渡交换其他的两个变量。因此可以用C++模版的知识,告诉编译器一个模子,让编译器根据不同类型 利用该模子来生成代码。其实本质上还是写了三个函数,只是模版是让编译器帮你写而已。
2024-04-26 20:05:04 800 12
原创 C++类和对象(上)
C++是面向对象的语言,对象其实可理解成客观事物,C++是面向过程的语言,他注重的是一步步过程。比如把一头大象塞进冰箱,C语言执行过程有三步,打开冰箱门,把大象塞进去,然后关上冰箱门。C++只关注对象,把大象塞进冰箱,有三个对象,人和大象以及冰箱,整个过程是人,大象,冰箱三个对象之间交互完成的,人不需要关注大象是怎么塞进冰箱的,冰箱是怎么关门的。在面向过程的编程中,程序员需要关注每一个步骤和细节,手动控制整个过程的执行。
2024-04-21 19:46:21 1043 8
原创 排序:冒泡排序,直接插入排序,简单选择排序,希尔排序,快速排序,堆排序,二路归并排序
前面的指针因为要保持数组的前半部分都小于基准值,所以遇到小于等于基准值的就直接跳过,往后走,直到找到大于基准值的元素。快速排序最好的情况是每一次划分都将n个元素划分为两个长度差不多相同的子区间,均匀二分也就是说每次划分所取的基准都是中值元素,划分的结果是基准的左,右两个无序子区间的长度大致相等,这样递归树高度为logn,而每一层划分的时间为O(n),因为需要遍历n个元素来进行比较和交换,虽然代码中是两重循环,但是l与r运行加起来最多也才整个数组的长度n,所以此时时间复杂度为O(nlogn)
2024-04-09 16:02:28 1091 5
原创 c语言贪食蛇游戏
贪食蛇游戏设计,分为游戏开始前和游戏运行以及游戏结束三个阶段,我这个是利用win32 API直接在命令框设计的游戏,游戏运行阶段主要是解决游戏界面,提示信息等方面。游戏运行阶段会去解决初始化蛇身和食物,以及根据按键情况去移动蛇的方面。游戏结束阶段会告知游戏结束的原因和释放链表节点(蛇身以及食物都是通过链表来表示,其实也可以通过动态顺序表来做),游戏结束一般来说会是撞墙结束,咬到自己结束,以及正常退出三种情况。
2024-02-06 22:30:30 6372 13
原创 c语言编译链接
本文将了解到c语言是怎么编译怎么链接的,c语言文件是怎么变成能够被计算机识别的文件底层处理。同时还将详细介绍预处理宏的相关知识。以及了解头文件的相关知识,比如#include与#include"stdio.h"的区别一.c语言的编译链接我们都知道计算机是无法直接识别人类语言的,它只能识别机器语言。如果不会外语而要与外国人交谈,通过翻译就可以把我的语言转变成他所能理解的语言。
2024-01-23 18:44:34 974 5
原创 c语言文件操作
我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作C语言中的流是一个抽象概念,它代表了数据的流动,可以是输入流或输出流。流的概念并不直接涉及到空间的划分,而是将数据的流动抽象为一个逻辑上的概念。
2024-01-17 17:13:36 1026 1
原创 图的操作实验
有下图所示的带权有向图及其对应的邻接矩阵,编写一个程序,实现图的各种基本运算和下面main函数中的每一步功能。(6)采用迪杰斯特拉算法求顶点0出发到达其他各顶点的最短路径及最短路径长度。依据所给的邻接矩阵,创建上图的邻接表存储,并输出邻接表结构;(3)加深图的深度优先遍历算法和广度优先遍历算法的理解。(4)领会最小生成树和最短路径问题的求解及相关算法设计。(4)采用克鲁斯卡尔算法求顶点0出发的一棵最小生成树。(1)掌握图的邻接矩阵和邻接表存储结构。(2)熟练图的邻接表的基本运算。
2023-12-28 18:17:17 613 6
原创 数据结构:线性表顺序存储结构———顺序表
int length;}SqList;是指把结构体类型名struct重命名为SqList,SqList是等价于struct的,SqList是类型名;如果没有typedef,直接struct {.......}SqList,那么SqList是结构体变量,不是类型名。开头定义了typedef char ElemType;,其实就是把char用ElemType表示了,ElemType其实就是char。而#define MaxSize 100等价于,MaxSize=100;
2023-12-23 19:38:24 2429 6
原创 动态内存管理,malloc和calloc以及realloc函数用法
malloc其实就是动态开辟空间,其实就是让程序员自己去决定开辟多大空间int a=5,在栈空间上开辟4个字节去存变量a,char b=1在栈空间上开辟1个字节去存变量b,包括数组char arr[10]以上空间都是固定的,这种开辟空间是编译器自动完成分配的,在程序运行之前就已经分配好了,编译器负责将源代码翻译成机器语言,并确定变量在内存中的存储方式和位置。操作系统负责管理内存并为程序分配空间,但编译器决定了变量在内存中的布局和大小。但是对于空间的需求,不仅仅是上述的情况。
2023-12-15 20:31:10 1337 6
原创 结构体相关知识
结构体说直白点就是自定义类型,c语言有很多内置的类型比如char,int,double等,而结构体就是我们自己命名的一种类型。区别在于内置类型大多都是单一描述的类型,比如 char studentname='wangwu',只能描述一种类型。学生的属性有很多,比如char 类型的名字,int 类型的学号,double类型的分数。当然你也可以挨个去定义,比如 char name[]="wangwu",int sno=2425678,double scole=85.6;
2023-12-09 19:54:49 1627 6
原创 整数以及浮点数在内存中的存储
大小端字序存储其实就是字节在内存中存储时的存储顺序。如果数据的低位字节内容保存在内存的高地址处,而高字节内容保存在内存的低地址处,那么就是大端存储模式如果数据的高位字节内容保存在内存的高地址处,而低字节内容保存在低地址处,那么就是小端存储模式比如15,它的十六进制补码为00 00 00 0f而在vs这个编译器中存储的情况是这样的编译器里默认左边是低地址,右边是高地址,而存储为00 00 00 00 0f,其实是按照低字节存低地址的规则来进行的,所以是小端存储。代码判断大小端存储。
2023-12-08 16:47:31 1075 6
原创 介绍一些字符串相关的库函数
strcpy函数功能其实就是把一个字符串复制到另一个字符串上,前提是目标空间足够大,以确保能放下整个复制过来的字符串。其次,目标空间必须是可修改的,而被复制的字符串没有修改的必要,所以会被const修饰被复制的字符串必须以\0结束,同时会把这个\0复制到目标空间当中去str++;stc++;num--;*str= '\0';return p;int main()与strcpy的代码实现大致相同,只是用num去控制循环赋值的次数。
2023-12-02 22:15:31 902 4
原创 指针数组,数组指针,字符指针,函数指针,二级指针介绍
一级指针解引用是*pa,得到a的值10,而二级指针解引用*ppa,得到的是一级指针变量pa保存的内容(也就是a的地址),再解引用一次**ppa,得到的依旧也是a的值10。同样数组指针也可以也可以加个的字来理解,即数组的指针,数组的指针本质上就是个指针,那么数组指针变量存放的其实就是数组的地址,是能够指向数组的指针变量。二维数组同样用上述打印的函数,传递的也是首元素地址,只不过不是单个元素了,而是一整个第一行数组的地址,这时候就得用数组的指针去接收这一整个数组的地址了。去掉指针变量的名字就是它的类型了。
2023-11-24 18:34:20 965 5
原创 指针的介绍
那么指针变量int *pa类型是什么呢,它的类型是int*,*号是在说明a是一个指针变量,而前面的int是在说明pa指向的是整型类型的对象。上面示例中指针加整数解引用和普通数组打印方法的结果是相同的,p一开始指向的是首元素地址,循环加i,它的地址也会随之往后偏移,此时i其实就是数组的下标。将地址保存起来是要使用的,那怎么使用的呢,我们只要拿到了地址(指针)就可以通过指针找到地址(指针)指向的对象,相当于我们使用地址要找到一个房间,在房间里可以拿走或者存放物品。这两没什么大的区别,就是同一个东西。
2023-11-23 12:51:17 155 2
原创 算法二 冒泡排序
冒泡排序指的是相邻两项两两相比,前一项如果比后一项大得话,就交换位置,然后依次与后面的数相比,直到遇到后一项比自己小。//如果后面的数字还没循环完就已经有序了就不用接下去执行没完成的循环了,简化了操作。for (i = 0;i++)//此次循环次数不会大于总个数,i从0开始所以要减1。for (j = 0;j++)//此次循环是两两相比要几次。//每交换一次就将find置为零。//设定如果有序就为1。
2023-11-13 22:54:22 58 3
原创 算法一 二分查找法
如果中间下标对应的数比我现在要查找的数大,那么就把中间下标的下一个作为的左值下标,重新折半取中间下标,重新比较中间值和要查找到的值的大小。如果中间的数比我现在要查找的数小,那么就把中间下标上一个作为右值下标,而左值下标保持不动,继续折半取中间值,重新比较中间值和要查找到的值,循环上面操作。//sizeof(arr)/sizeof(arr[0])用数组总字节长度除以单个字节长度就得到元素总个数了,而减一得到数组末尾元素下标,因为数组下标从0开始,所以减一才是末尾元素下标。//设定左下标为数组的首元素的下标。
2023-11-13 18:50:28 151 1
原创 c语言版简易扫雷
单独设置一个get()函数来计算雷的个数 ,另外八个坐标为arr1[x-1][y] arr1[x-1][y-1] arr1[x][y- 1] arr1[x+1][y-1] arr1[x+1][y] arr1[x+1][y+1] arr1[x][y+1] arr1[x-1][y+1] ,用这八个坐标值相加就知道有多少个雷,再分别减‘0’就可以显示几个雷了。2.建立一个数组arr2用来存放雷的信息,用字符‘1’来表示雷,有雷就存放1,没有雷就存放0。而字符型个数=数字+字符0。
2023-11-05 16:57:38 111 3
原创 c语言分支循环浅介绍(下)
for循环里面break与while差不多,但是continue有区别,因为for循环调整部分和判断部分集中在一块,所以continue的跳过后面的语句并不会影响for循环的调整,而仅仅只会跳过a=5,所以结果是0,1,2,3,4,6,7,8,9,10。continue在英文里是继续的意思,在c语言中它是跳过本次循环以及continue的语句,因为a++在continue后面,所以被跳过了会一直拿a=5去做判断,最后陷入死循环,而break是直接就结束了。同样的例子,打印0到10的数字。
2023-10-28 17:51:44 54 1
原创 c语言分支循环浅介绍(上)
而break可以看作是这条河流经途中的闸门,有了break闸门就可以截断河流,不让它继续往下流了(即不执行下面剩下的语句了)。举个简单的例子,假设分数大于445分是二本线,而在大于445分基础上518分是一本线,一本线以上又可以分为(小于600分)的普通一本和(大于600分)的985,211学校。值得注意的是else并不是和哪个if对齐就是和哪个是一队,如果写代码很混乱分不清的时候,else是和自己最近的if相匹配的,不能乱点鸳鸯谱啊。比如下面的例子,我的本意是只打印1月的天数就行,可是它却全打印出来了。
2023-10-28 16:41:52 47 1
原创 c语言猜数字游戏
*/n的余数范围是0到n - 1,得到随机数范围是0到100 如果是a到b的随机数范围是a + rand(b - a + 1);/*srand函数是用来初始化随机数的生成器,原型srand(unsigned int seed)*/srand((unsigned int)time(NULL));printf("猜数字游戏,请输入\n");printf("游戏结束\n");printf("猜大了\n");printf("猜小了\n");printf("猜对了\n");printf("出错了\n");
2023-10-23 22:47:17 85 3
原创 实现顺序栈的各种基本运算的算法
printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("依次进栈元素a,b,c,c,d,e\n");printf("顺序栈的基本运算\n");printf("初始化栈\n");printf("释放栈\n");
2023-10-21 17:16:25 561 2
原创 链栈实验,实现链栈的各种基本运算
printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("判断栈s是否非空: %s\n", (StackEmpty(s)?"空" : "非空"));printf("依次进栈元素a,b,c,d,e\n");printf("链栈的各种基本运算\n");printf("初始化栈\n");printf("释放栈\n");
2023-10-21 16:04:31 259 1
空空如也
这是为啥啊,一模一样还是提示错误
2023-11-21
见笑了,刚开始学这个
2023-09-28
TA创建的收藏夹 TA关注的收藏夹
TA关注的人