C语言
文章平均质量分 89
关于C语言的一些知识整理
我没有空军
这个作者很懒,什么都没留下…
展开
-
排序(五)——非比较排序+排序总结
我们前面学了几种比较排序,这里我们对他们进行一个总结时间复杂度直接插入排序:O(N^2)希尔排序: O(N^1.3)选择排序: O(N^2)堆排序: O(NlogN)冒泡排序: O(N^2)快排: 最好O(NlogN),最坏O(N^2),但是三数取中优化之后一般不会出现最坏归并排序: O(NlogN)空间复杂度直接插入排序:O(1)希尔排序: O(1)选择排序: O(1)原创 2024-04-19 07:00:00 · 959 阅读 · 0 评论 -
排序(四)——归并排序 + 外排序
目录1.归并排序递归实现代码2.归并排序非递归代码3.比较快排、归并和堆排序4.归并排序实现外排序我们之前对两个有序数组进行排序就用到了归并的思想,对于两个有序数组,我们分别取他们首元素比较大小,取小的插入到一个新开辟的数组中,归并排序的前提就是要有两个有序序列,而且还要开辟一块新的空间来存放新的有序的数组。那么对于一个无序的数组该如何使用归并排序呢这一整个数组我们可以把它分成左右两个区间来看,一个是 [0,4] ,一个是 [5,9] ,而只要这两个区间有序了,我们就有办法通过控制下标来进行归并排序。怎么使原创 2024-04-18 07:00:00 · 1253 阅读 · 0 评论 -
排序(一)——插入排序 希尔排序
试想,当原数组的数据是接近逆序的时候,他的大的数据在前面,而小的数据在后面,如果采用直接排序的话就需要一个位置一个位置交换,十分的耗时,当我们用预排序的话,他不是一次只移动一个位置,而是一次移动gap个位置,这样一来能让小的数据更快地来到数组的前面,大的数据也能更快的调换到后面,使得原本逆序的数组变得更接近有序,更有利于插入排序。同时,希尔排序一般是用于排序数据量很大的时候,这时候也能让更大的数据更快的到后面,小的数据更快的到前面,这样优化了直接插入排序。我们可以认为,只有一个数据的时候他就是有序的。原创 2024-04-15 18:40:51 · 623 阅读 · 0 评论 -
二叉树(二)———链式二叉树结构
二叉树的链式结构以及基础遍历原创 2024-04-14 22:05:54 · 1313 阅读 · 0 评论 -
二叉树(一)———树的概念 + 堆与堆排序
详细讲解了树的常用概念以及二叉树,同时实现二叉树的线性结构——堆和堆排序原创 2024-04-12 21:29:10 · 1211 阅读 · 0 评论 -
队列实现栈———栈实现队列
首先我们要把之前实现的队列的代码复制粘贴到oj中,原创 2024-04-10 20:16:09 · 1053 阅读 · 0 评论 -
栈和队列的实现
前面我们讲解了常见的线性数据结构,今天再来学习两种特殊的线性数据结构。原创 2024-04-08 21:41:36 · 558 阅读 · 0 评论 -
顺序表和链表
而我们写的这些数据结构的程序都是存储在内存中的,也就是上图中的主存,而代码经过编译之后是要到我买电脑的cpu中去执行的,代码运行过程中呢,cpu就会去访问我们的数据,由于 cpu 的访问速度很快,而如果cpu是直接去内存中访问的话,内存的访问速度又相对而言慢,这时候cpu的性能就没发挥出来,程序运行速度就会很慢。因为顺序表是连续存储的,所以加载顺序表的数据到缓存中时不知会把这一个数据加载进来,而是会加载多个数据(具体取决于cpu的字长),再访问后面的数据时可能就直接能在缓存中查找到了。原创 2024-04-08 17:57:50 · 1177 阅读 · 0 评论 -
带头双向循环链表实现
虽然带头双向循环链表的结构比单链表要复杂的多,但是他的结构带来的优势就是增删的操作都十分简单,而且头插尾插能完全复用插入函数,头删尾删也能完全复用删除函数,代码量变小了很多,只要我们理解了指针之间的逻辑关系,这种结构使用起来就十分方便了。原创 2024-04-07 22:44:15 · 887 阅读 · 0 评论 -
单链表经典oj题 (一) 简单
我们不能去遍历链表,但是我们能找到要删除的节点的下一个节点,这个题的要求是删除那个数据,并不是说要删除这个节点,那么我们就可以将要删除的节点的数据与下一个结点的数据进行调换,这样问题就转换为了删除下一个节点了,怎样处理就很简单了。首先我们是可以求出两个链表的节点的个数的,也就是链表的长度,当链表相交之后后半段的长度是相等的,所以两个链表的长度差就差在相交之前的部分。那么我们是不是可以让长的链表先走 他们的长度差 的步数,如何在两个指针一起走,这样他们相遇的节点就是相交的起始节点。原创 2024-04-07 06:00:00 · 696 阅读 · 0 评论 -
无头单向非循环链表的实现
以上就是单链表的实现,它的优势就是头插头删很方便,效率很高,但是单链表除了头部操作,其他的操作都很不适合,想要做到任意位置的高效的插入删除还是要看后面要学的带头双向循环链表。原创 2024-04-06 19:23:17 · 1331 阅读 · 0 评论 -
顺序表的实现
define INIT_CAPACITY 10//初始的容量和每次增长的容量//维护动态数组//数据个数//数组容量}SL;这就是顺序表的简单实现了。原创 2024-04-05 22:55:10 · 950 阅读 · 0 评论 -
通讯录改造———文件版本
上一篇文章我们详细讲了文件操作,这时候我们就可以把通讯录保存到文件中,这样即使程序退出了,联系人的信息也还是保存着,下一次启动程序时我们就可以把文件中的数据读取到程序中来使用。原创 2024-04-02 02:00:00 · 720 阅读 · 0 评论 -
C语言文件操作
简单来说,硬盘上的文件就是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。(以文件功能的角度来分类)程序文件包括源文件(.c)、目标文件(.obj)、可执行程序(.exe)数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据(把文件的内容读到内存中),或者输出内容的文件(把内存中的数据写到文件中)。我们在这篇文章里讲的就是数据文件这么多文件怎么使用呢?这就涉及到了文件的唯一标识:文件名。原创 2024-04-01 20:19:52 · 923 阅读 · 0 评论 -
通讯录改进———动态版本
首先我们将联系人列表初始化一定的空间,假设我们设定初始最大联系人数量为3,我们可以在头文件中用#define来定义,方便后续修改.与此同时,我们也可以用#define来定义每次扩容的空间。要将其改为动态版本主要是两件事,首先初始化的时候我们要动态开辟data的空间,光动态开辟还不够,我们还要增加一个变量来记录当前联系人列表的大小,空间使用完之后要记得释放。在上一篇博客中讲完了动态内存分配,这时候我们就可以改进之前写的通讯录了,可以将其升级为动态内存的版本,既不用担心联系人满了,也不用担心内存浪费太大。原创 2024-03-29 20:49:06 · 393 阅读 · 0 评论 -
C语言--动态内存管理
为什么存在动态内存管理?在之前我们讲到的类型创建的变量再空间开辟好之后就不能再改变了,但是有时候我们希望能够自由地为某个变量分配空间,就比如上一篇文章中的通讯录,在没有动态内存管理情况下,我们就只能为通讯录开辟一点的空间,开辟之后就不能再更改了,如果一开始开辟的空间过大,可能会造成很大的浪费,如果一开始开辟的空间很小,那就可能不够用,当我们能够做到有几个联系人就开辟多大的空间时,空间利用率就会大大提升。这就是我们要讲的动态内存管理。原创 2024-03-28 20:10:02 · 1101 阅读 · 0 评论 -
自定义类型
结构体有两种定义形式,一种是在声明时直接在变量列表中定义,另外一种是用这个结构体类型去创建变量,这两种多余的时候都能直接对变量初始化。在对结构体初始化的时候要用一个大括号,与数组一样,对多个元素同时赋值要用大括号括起来。如果一个结构体内部包含另一个结构体,在初始化的时候,内部的结构体的初始化也要用一个大括号括起来。int score;原创 2024-03-26 21:10:28 · 1189 阅读 · 0 评论 -
模拟实现字符串库函数(一)
在C语言的标准库中提供了很多针对字符串的库函数,这篇文章我们会学习并模拟实现几个简单的库函数。原创 2024-03-24 20:39:14 · 624 阅读 · 1 评论 -
模拟库函数qsort实现不同类型元素的冒泡排序
这里的base是 void* 类型的,而void* 可以接受任意类型的指针变量,且 void* 类型的指针不可被解引用,简单来说,void* 是一个泛型指针,我们在传参的时候可以传任意类型的指针,base都能接受,等到要用的时候再把它强制转换成所需要的类型的指针来解引用。在介绍中说了,这个比较函数会在qsort中重复调用来比较两个数据,这个函数的返回类型为int,当p1 的内容大于p2的内容时,返回一个大于零的数,当p1的内容等于p2的内容时,返回零,否则返回小于零的数。这样就能得到降序了。原创 2024-03-21 19:48:31 · 892 阅读 · 1 评论 -
C语言指针进阶
这篇文章介绍的是一些关于指针的更加深入的知识。原创 2024-03-20 20:41:12 · 1543 阅读 · 1 评论 -
数据在内存中的的存储
内置类型long 类型的大小是 4 / 8 个字节,元素C语言规定 sizeof(long)>= sizeof(int)就行。在32位平台上,long为4个字节,在64位平台上,long位8个字节。类型的意义1.使用这个类型开辟内存空间的大小(内存大小决定了适用范围)2.如何看待内存的视角。(数据存储到内存中和从内存中读取的方式)在上面的代码中,我们发现在内存中的数据好像是以字节为单位反着存的。大小端介绍 ,以十六进制数 0x 11 22 33 44为例。原创 2024-03-19 20:47:04 · 1036 阅读 · 1 评论 -
程序调试技巧
导致程序出错或者无法正常工作的问题或者错误。原创 2024-03-18 20:56:57 · 999 阅读 · 1 评论 -
初阶结构体
我们可以在声明的时候定义结构体全局变量,也可以在函数内部定义结构体局部变量;结构体初始化可以用一个大括号,在大括号里面对成员变量依次赋初值;结构体嵌套是初始化也是用大括号赋初值,里面的结构体再用一个大括号赋初值。结构体初始化也可以不完全初始化,比如只对前几个成员变量赋初值。int main()struct stu s1 = { "zhangsan",13,"男","111111111111" };原创 2024-03-17 20:03:45 · 362 阅读 · 1 评论 -
C语言初阶指针
我们首先知道,不同类型的变量在内存中存储的方式是不一样的,所占内存大小也是不一样的,我们创建指针的目的最终还是要通过指针来访问指针指向的对象,虽然指针变量的大小是一样的,但是他们访问的权限和访问内存的方式是不一样的。在比如,虽然int *和float*的指针都能访问四个字节,访问权限和加减整数跳过的大小也是一样的,但是因为他们在内存中的存储不一样,当我们对跟指向的对象不同类型的指针解引用修改指向的对象时,是以该指针的类型来决定用什么方式修改的。在我们用指针访问数组时,超出数组范围的访问就是越界访问。原创 2024-03-16 02:00:00 · 865 阅读 · 1 评论 -
C语言 操作符
通过这个案例我们可以发现,异或两次相同的数就等于原来的数,因为两个相同的数异或为0,而任何数与0异或都是原来的数,同时我们也可以得知异或是满足交换律的。负整数的反码和补码是需要计算的。因为表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节大小一般就是int的字节长度,同时也是通用寄存器的长度。运算时将内存小的转换成内存大的、位操作符和移位操作符结合在一起是能够实现很多有趣的功能的,比如将数据的特定的一个二进制位改为0或1,我们可以很轻松的使用这是操作符来达到。原创 2024-03-15 02:00:00 · 836 阅读 · 1 评论 -
递归经典问题——汉诺塔、青蛙跳台阶
这时候B上有n-1个盘子,A上没有盘子,C上有一个最大的盘子,而C上面的最大的盘子不影响其他比它小的盘子挪到C上,且这个最大的盘子已经放在他应该在的位置,不会再挪动,这时候问题就回到了最初的问题,只是将n变成了n-1,也就是还需要 f ( n-1)步就能将所有的盘子都挪到C上,所以总共的步数为 f ( n ) = 2*f (n-1)+1。假设青蛙跳到第n步的方法有f (n )种,而青蛙有两种方法跳到第n步,一种是从n-1跳到n,一种是从n-2跳到n,所以 f (n ) = f (n-1)+ f(n-2)原创 2024-03-14 07:00:00 · 1468 阅读 · 0 评论 -
C语言函数
库函数虽然提供了我们常用的功能,但是在写程序的时候更重要的还是自定义函数,这是由我们程序员自己创建的函数,自定义函数也有函数名、返回类型、函数参数等,最重要的时函数体,因为函数体的代码才是我们函数功能的实现。返回类型 函数名 (函数参数);函数的声明就是告诉编译器有一个函数叫什么,参数是什么,返回类型是什么,但是具体存不存在函数声明决定不了,有时候会出现假声明的情况,即声明了,但是没有函数的具体实现(定义)。函数的声明一般出现在函数使用之前,要满足先声明后使用。原创 2024-03-10 19:26:52 · 826 阅读 · 1 评论 -
粗谈函数栈帧的创建与销毁
本文对函数栈帧的创建和销毁进行了粗浅的分析,对于理解函数具有十分重要的意义原创 2024-03-09 19:37:35 · 1344 阅读 · 0 评论 -
初学C语言设计一个简单的猜数字小游戏
一个适合初学者设计的小游戏,主要涉及到随机数的生成,循环的使用等简单的知识点原创 2024-03-07 20:05:59 · 1423 阅读 · 0 评论 -
C语言初阶入门-初识C语言
比特位太小了,我们我们没必要将内存划分得那么细致,管理起来太过麻烦,就拿C语言来说,最小的数据类型char就要用到一个字节,也就是八个比特位,如果用比特位作为内存划分最小单位的话,这就需要八个内存编号,这其实是没有必要的,同时也造成了很多的浪费。在C语言中,const修饰的a本质是变量,但是不能被修改,有常量的属性。指针变量的大小,指针变量的大小并不是有指针所指向的变量类型决定的,而是有电脑环境决定的,不管是什么类型的指针,都是在创建指针变量,指针变量的大小取决于一个地址存放的时候需要多大的空间。原创 2024-03-05 21:04:42 · 914 阅读 · 0 评论 -
分支与循环语句
C语言语句可分为以下五类:1.表达式语句2.函数调用语句3.控制语句4.复合语句5.空语句我们这里介绍的是控制语句C语言是一种结构化的程序设计语言,生活中的事物常见的结构有顺序,选择,循环结构,C语言的控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句,可以分为以下三类:1、条件判断语句也叫分支语句:if语句、switch语句;2、循环执行语句:do while语句、while语句、for语句;原创 2024-03-06 21:43:10 · 750 阅读 · 0 评论