- 博客(58)
- 收藏
- 关注
原创 【数据结构与算法】第18篇:数组的压缩存储:对称矩阵、三角矩阵与稀疏矩阵
在科学计算和工程应用中,经常遇到特殊矩阵——大量元素重复或为零。如果直接用二维数组存储,会浪费大量空间。这一篇我们学习如何压缩存储这些特殊矩阵:对称矩阵只存一半,三角矩阵只存三角部分,稀疏矩阵只存非零元素。重点讲解稀疏矩阵的三元组表示法和快速转置算法。
2026-03-31 22:43:33
32
原创 【数据结构与算法】第17篇:串(String)的高级模式匹配:KMP算法
上一篇的BF算法虽然简单,但效率低,因为它会在匹配失败时让主串指针回溯。KMP算法通过利用已匹配部分的信息,让主串指针不回溯,从而将时间复杂度优化到O(n+m)。这一篇我们重点讲解next数组的推导过程,理解“部分匹配”如何避免重复比较。这是专栏的第一个难点,建议你拿出纸笔,跟着推导一遍。
2026-03-31 22:40:40
93
原创 【数据结构与算法】第16篇:串(String)的定长顺序存储与朴素模式匹配
字符串是编程中最常用的数据类型之一。这一篇我们回到C语言,看看字符串的本质——字符数组。我们会实现串的定长顺序存储结构,然后重点讲解朴素模式匹配算法(BF算法)。BF算法虽然简单粗暴,但它是理解更高级的KMP算法的基础。通过这个算法,你能深刻理解“回溯”的概念和模式匹配的基本思路。
2026-03-30 22:36:21
225
原创 【数据结构与算法】第15篇:队列(二):链式队列的实现与应用
上一篇我们实现了循环队列,这一篇用链表实现队列。链式队列没有容量限制,不会溢出。更重要的是,队列是广度优先搜索(BFS)的核心数据结构。我们会用链式队列实现一个简单的迷宫寻路程序,展示BFS如何利用队列的“先进先出”特性找到最短路径。
2026-03-30 22:34:38
282
原创 【数据结构与算法】第14篇:队列(一):循环队列(顺序存储
队列是一种先进先出(FIFO)的线性表,像排队一样,先来的先服务。用数组实现队列时,会出现“假溢出”问题——队尾满了但队头还有空位。循环队列通过取模运算解决了这个问题。这一篇我们实现循环队列,重点讲清楚队空和队满的区分方法,以及入队、出队操作中取模运算的使用。
2026-03-29 22:56:04
311
原创 【数据结构与算法】第13篇:栈(三):中缀表达式转后缀表达式及计算
我们平时写的 3+4*2 叫中缀表达式,但计算机处理起来很麻烦,因为要考虑优先级和括号。后缀表达式(逆波兰表达式)3 4 2 * + 没有括号、没有优先级问题,计算机用栈就能轻松计算。这一篇我们讲如何把中缀转后缀,以及如何计算后缀表达式,最终实现一个简单的四则运算计算器。
2026-03-29 22:36:46
356
原创 【数据结构与算法】第12篇:栈(二):链式栈与括号匹配问题
上一篇我们用数组实现了顺序栈,这一篇用链表实现链式栈。链式栈没有容量限制,不会溢出。然后我们讲栈的经典应用——括号匹配。在编程语言中,括号必须成对出现且嵌套正确,这个检查过程完美契合了栈的“后进先出”特性。我们会用C语言字符数组来存储表达式,通过栈来判断括号是否匹配。
2026-03-28 22:32:50
490
原创 【数据结构与算法】第11篇:栈(一):顺序栈的实现与进制转换
栈是一种特殊的线性表,它限制了数据的插入和删除只能在一端进行,这就是“后进先出”特性。这一篇我们实现顺序栈(用数组实现),包括入栈、出栈、取栈顶等操作。然后通过一个经典应用——十进制转二进制,来展示栈的实际用途。进制转换中“除基取余、逆序输出”的过程,完美契合了栈的特性。
2026-03-28 22:31:06
544
原创 【数据结构与算法】第10篇:项目实战:学生信息管理系统(线性表版)
前9篇我们学了顺序表、单链表、双向链表等线性结构。这一篇来做个实战项目:学生信息管理系统。我们会用单链表来存储学生信息,实现增删改查功能,并采用模块化设计,把代码拆分成.h和.c文件。这是一个完整的命令行小项目,你可以把它当作数据结构学习的第一个综合练习。
2026-03-27 22:33:15
432
原创 【数据结构与算法】第9篇:线性表(五):静态链表
在早期的编程语言中,并没有指针这个概念。那如何实现链表呢?静态链表就是一种用数组模拟链表的技巧。它用数组下标代替指针,用游标(cursor)来指向下一个元素的位置。虽然现在C语言有指针,很少需要这样写,但理解静态链表的原理,能帮你更深刻地理解链式结构的本质。这一篇我们就用C语言实现一个静态链表,并对比它与动态链表的区别。
2026-03-27 22:31:40
329
原创 【数据结构与算法】第8篇:线性表(四):双向链表与循环链表
单链表只能单向遍历,删除节点时必须知道前驱,这限制了它的灵活性。这一篇我们讲双向链表和循环链表。双向链表每个节点多了一个指向前驱的指针,插入和删除操作更高效。循环链表则把首尾连接起来,非常适合解决约瑟夫环这类循环问题。我们会手写双向链表的增删改查,并用循环链表实现约瑟夫环。
2026-03-26 22:42:02
326
原创 【数据结构与算法】第7篇:线性表(三):单链表的经典面试题(反转、找中间节点)
上一篇我们实现了单链表的基本操作。这一篇来点实战,讲几个单链表的经典面试题。反转链表、找中间节点、判断是否有环、找倒数第k个节点,这些都是面试高频题。我们会用C语言指针来实现,重点讲清楚快慢指针这个常用技巧。纯算法篇,不涉及具体应用,专注代码逻辑。
2026-03-26 22:39:32
337
原创 【数据结构与算法】第6篇:线性表(二):单链表的实现(头插法、尾插法)
上一篇我们讲了顺序表,它的插入和删除需要移动大量元素。这一篇我们讲单链表,它用“链”的方式把数据串起来,插入和删除只需要修改指针,不需要移动数据。我们会讲清楚结构体自引用是怎么回事,头结点(哑结点)到底有什么用,然后手写链表的创建、遍历、插入、删除。头插法和尾插法是两种常见的创建方式,也会一起讲清楚。
2026-03-25 22:39:24
406
原创 【数据结构与算法】第5篇:线性表(一):顺序表(ArrayList)的实现与应用
从这篇开始,我们正式进入数据结构的世界。第一个登场的是顺序表,也就是动态数组。它把数据存在连续的内存空间里,像数组一样支持随机访问。但插入和删除要移动大量元素,这是它的特点也是局限。我们会手写增删改查,重点讲清楚插入和删除时数据是怎么移动的,以及动态扩容的realloc策略该怎么设计。
2026-03-25 22:37:29
612
原创 【数据结构与算法】第4篇:算法效率衡量:时间复杂度和空间复杂度
写了一个算法,怎么判断它好不好?靠感觉?当然不是。这一篇我们聊时间复杂度和空间复杂度,这两个指标是衡量算法效率的黄金标准。大O表示法怎么用?最好、最坏、平均情况分别指什么?二分查找为什么快?斐波那契数列的递归为什么慢?通过几个经典例子,把这些概念彻底搞清楚。
2026-03-24 22:52:14
393
原创 【数据结构与算法】第3篇:C语言核心机制回顾(二):动态内存管理与typedef
写数据结构,绕不开动态内存分配。链表的一个节点、树的一个结点,都是在程序运行时动态创建的。这篇我们讲 malloc、calloc、realloc、free 这四个函数怎么用,什么时候用,以及最让人头疼的内存泄漏问题怎么避免。顺便把 typedef 的用法再深入一下。
2026-03-24 22:49:27
395
原创 【数据结构与算法】第2篇:C语言核心机制回顾(一):指针、数组与结构体
写数据结构之前,必须先搞懂C语言里几个核心概念。这篇我们聊指针、数组和结构体。指针怎么运算?数组名到底是个什么东西?结构体的大小为什么不是成员大小简单相加?这些搞不清楚,后面写链表的时候很容易踩坑。
2026-03-23 22:14:57
521
原创 【数据结构与算法】第1篇:为什么要学习数据结构与算法?专栏导学
这是本专栏的开篇。我会聊聊为什么要学数据结构与算法,本专栏会写哪些内容、按什么顺序学,以及如何搭建C语言的开发环境。如果你刚学完C语言基础,正不知道该往哪个方向走,这篇可以给你一个清晰的路线图
2026-03-23 22:13:03
193
1
原创 【C语言程序设计】第40篇:综合项目实践:基于C语言的学生信息管理系统
本文是C语言程序设计专栏的第四十篇,也是整个专栏的收官之作。在前39篇中,我们系统学习了C语言的基础语法、数据类型、控制结构、数组、指针、结构体、动态内存、文件操作等核心知识。现在,我们将综合运用这些知识,完成一个完整的项目——学生信息管理系统。本文将按照软件工程的标准流程,从需求分析开始,逐步完成模块划分、数据结构设计、功能实现、文件持久化等环节,最终交付一个功能完整的学生信息管理系统。
2026-03-22 22:38:46
293
原创 【C语言程序设计】第39篇:预处理器与宏定义
本文是C语言程序设计专栏的第三十九篇。在前几篇学习了动态内存管理和链表后,现在需要掌握C语言中一个重要的工具——预处理器。预处理器在编译之前对源代码进行文本处理,宏定义、文件包含、条件编译等功能都是通过预处理器实现的。理解和善用预处理器,可以写出更灵活、更易维护的代码。本文将系统介绍#define定义符号常量和宏函数,详细讲解条件编译的应用场景,深入剖析#和##运算符的特殊用法,并通过实例展示预处理器在实际开发中的强大能力。
2026-03-22 22:36:24
376
原创 【C语言程序设计】第38篇:链表数据结构(二):链表的插入与删除操作
本文是C语言程序设计专栏的第三十八篇。在上一篇学习了链表节点的定义和基本操作后,现在需要深入掌握链表的核心操作——插入与删除。链表之所以灵活高效,正是因为插入和删除只需修改指针,而不需要移动数据。本文将系统介绍头插法、尾插法、指定位置插入的实现细节,详细讲解删除头节点、尾节点、中间节点时的指针修改逻辑,并通过完整的代码示例展示各种操作的正确实现。
2026-03-21 23:09:09
361
原创 【C语言程序设计】第37篇:链表数据结构(一):单向链表的实现
本文是C语言程序设计专栏的第三十七篇。在前几篇学习了动态内存管理和结构体后,现在需要掌握一种重要的动态数据结构——链表。数组在内存中是连续存储的,插入和删除操作需要移动大量元素;而链表通过指针将分散的节点连接起来,可以灵活地插入和删除节点,是C语言中实现动态数据集合的基础。本文将系统介绍链表节点的结构体定义,详细讲解动态创建节点的方法,深入演示链表的遍历与释放操作,并通过实例展示单向链表的完整实现。
2026-03-21 23:04:11
394
原创 【C语言程序设计】第36篇:二进制文件的读写
本文是C语言程序设计专栏的第三十六篇。在前一篇学习了文本文件的读写后,现在需要掌握二进制文件的读写操作。二进制文件以数据在内存中的原始形式存储,读写效率高、存储紧凑,是存储大量结构化数据的理想选择。本文将系统介绍fread和fwrite函数的使用方法,深入讲解数据块读写的原理,详细演示文件定位函数fseek和ftell的应用,并通过实例展示如何读写结构体数组等复杂数据。
2026-03-20 22:42:14
367
原创 【C语言程序设计】第35篇:文件的打开、关闭与读写操作
本文是C语言程序设计专栏的第三十五篇。在前一篇学习了文件的基本概念和文件指针后,现在需要掌握文件的具体操作——如何打开和关闭文件,如何读取和写入数据。C语言提供了丰富的文件读写函数,从字符级到字符串级再到格式化读写,满足不同场景的需求。本文将系统介绍fopen函数的各种模式参数,深入讲解fclose的必要性,详细演示字符读写(fgetc/fputc)、字符串读写(fgets/fputs)、格式化读写(fprintf/fscanf)函数的使用方法,并通过实例展示如何根据实际需求选择合适的读写方式。
2026-03-20 22:39:58
372
原创 【C语言程序设计】第34篇:文件的概念与文件指针
本文是C语言程序设计专栏的第三十四篇。在前几篇学习了动态内存管理后,现在需要掌握如何将数据持久化保存——文件操作。文件是程序与外部世界交互的重要方式,理解文件的概念和C语言中的文件操作机制,是编写实用程序的基础。本文将系统介绍文本文件与二进制文件的区别,详细讲解流的概念及其在C语言中的实现,深入剖析FILE结构体与文件指针的关系,为后续的文件读写操作打下基础。
2026-03-19 22:46:51
357
原创 【C语言程序设计】第33篇:二级指针与指针数组
本文是C语言程序设计专栏的第三十三篇。在前几篇学习了指针的基本概念、指针与数组的关系后,现在需要进一步探索更高级的指针用法——指向指针的指针(二级指针)以及指针数组。这些概念在动态数据结构、多维数组处理、命令行参数解析等场景中至关重要。本文将系统介绍二级指针的定义与使用,深入辨析指针数组与数组指针这两个容易混淆的概念,并剖析命令行参数 argv 的实质,揭示其在内存中的存储结构。
2026-03-19 22:44:58
342
原创 【C语言程序设计】第32篇:动态内存管理
本文是C语言程序设计专栏的第三十二篇。在前几篇学习了指针的各种应用后,现在需要掌握如何动态地管理内存——在程序运行时根据需要分配和释放内存。动态内存管理是C语言强大而危险的特性之一,它让我们能够灵活处理大小可变的数据,但也带来了内存泄漏、悬空指针等风险。本文将系统介绍堆与栈的区别,详细讲解malloc、calloc、realloc与free的配对使用规则,深入剖析内存泄漏的成因与检测方法。
2026-03-18 22:09:57
398
原创 【C语言程序设计】第31篇:指针与函数
本文是C语言程序设计专栏的第三十一篇。在前几篇学习了指针的基本概念及其与数组、字符串的关系后,现在需要探索指针与函数的结合——这是C语言中实现灵活设计和高级功能的关键。指针可以作为函数参数,实现“输出参数”的效果;函数本身也有地址,可以被指针指向和调用;函数指针更是实现回调机制的基础。本文将系统介绍指针作为函数参数的典型应用,详细讲解函数指针的定义与调用方法,并通过实例展示函数指针作为回调函数的强大能力。
2026-03-18 22:07:13
384
原创 【C语言程序设计】第30篇:指针与字符串
本文是C语言程序设计专栏的第三十篇。在前一篇学习了指针与数组的关系后,现在需要将这些知识应用到字符串处理中。C语言中没有专门的字符串类型,字符串是以字符数组或字符指针的形式存在的。理解字符指针和字符数组的区别,对于正确使用字符串至关重要。本文将系统介绍字符指针与字符数组的本质区别,深入剖析字符串常量的存储位置与只读特性,详细讲解如何用指针数组处理字符串表(如命令行参数、菜单选项等)。
2026-03-17 22:43:32
374
原创 【C语言程序设计】第29篇:指针与数组的关系
本文是C语言程序设计专栏的第二十九篇。在前一篇学习了指针的基本概念后,现在需要深入理解指针与数组之间密不可分的关系。在C语言中,数组和指针有着深刻的联系——数组名在很多场合下被当作指针使用,而指针也可以通过下标来访问元素。理解这种关系,对于写出灵活、高效的代码至关重要。本文将系统介绍数组名的指针常量属性,详细讲解通过指针访问数组元素的多种方式,深入剖析下标运算与指针运算的等价性,并通过实例展示这种等价关系的实际应用。
2026-03-17 22:39:22
323
原创 【C语言程序设计】第28篇:指针的概念与指针变量
本文是C语言程序设计专栏的第二十八篇。指针是C语言中最重要、最核心的概念,也是初学者最容易困惑的地方。指针提供了直接操作内存的能力,使C语言成为系统级编程的首选语言。理解指针的本质,是掌握C语言的必经之路。本文将系统介绍内存地址的基本概念,详细讲解指针变量的定义与初始化,深入剖析取地址运算符(&)和间接访问运算符(*)的用法,并重点讨论空指针与野指针的区别与防范。
2026-03-16 23:13:34
401
原创 【C语言程序设计】第27篇:递归函数原理与实例分析
本文是C语言程序设计专栏的第二十七篇。在前几篇学习了函数的基本概念后,现在需要掌握一种特殊的函数形式——递归函数。递归是一种强大的编程技术,它允许函数调用自身,从而用简洁的代码解决复杂的问题。递归的本质与数学归纳法有着深刻的联系,而其底层实现依赖于栈结构。本文将系统介绍递归的数学基础(数学归纳法),深入剖析递归的栈实现机制,并通过阶乘和斐波那契数列两个经典案例,详细对比递归与迭代的优劣。
2026-03-16 23:06:49
371
2
原创 【C语言程序设计】第26篇:变量的作用域与生命周期
本文是C语言程序设计专栏的第二十六篇。在前几篇学习了函数和参数传递后,现在需要深入理解变量在程序中的存在时间和可见范围——作用域与生命周期。这两个概念决定了变量在哪里可以被访问,以及它在内存中存在多久。C语言中的变量根据定义位置和存储类别的不同,表现出完全不同的行为。本文将系统介绍局部变量、全局变量、静态局部变量的存储类别,详细讲解它们的作用域和生命周期,并通过实例展示它们之间的区别与联系。
2026-03-15 22:45:27
353
原创 【C语言程序设计】第25篇:参数传递机制:值传递与地址传递
本文是C语言程序设计专栏的第二十五篇。在上一篇学习了函数调用的底层机制后,现在需要深入理解参数传递的两种方式——值传递和地址传递。C语言中所有参数传递本质上都是值传递,但通过指针可以实现类似其他语言中“引用传递”的效果。理解这一区别,对于编写正确、高效的函数至关重要。本文将系统介绍值传递的本质(传递实参的副本),详细讲解如何利用指针模拟引用传递以实现对实参的修改,并介绍const限定符在函数参数中的保护作用。
2026-03-15 22:39:02
383
原创 【C语言程序设计】第24篇:函数调用机制与栈帧
本文是C语言程序设计专栏的第二十四篇。在上一篇学习了函数的定义、声明与调用后,现在需要深入理解函数在底层是如何工作的。当函数被调用时,系统如何在内存中为它分配空间?参数如何传递?返回值如何返回?这些都是理解程序执行机制的关键。本文将系统介绍函数调用时的栈帧结构,详细讲解参数的压栈顺序与传递机制,深入剖析返回值的传递方式,并通过实例展示函数调用过程中的内存变化。理解这些底层机制,有助于写出更高效、更可靠的代码。
2026-03-14 22:02:53
314
原创 【C语言程序设计】第23篇:函数的定义、声明与调用
本文是C语言程序设计专栏的第二十三篇。在前几篇学习了各种数据类型和控制结构后,现在需要掌握C语言中实现模块化编程的核心工具——函数。函数允许我们将程序分割为独立的功能模块,每个模块完成特定的任务,通过参数传递数据,通过返回值返回结果。理解函数的定义、声明与调用机制,是编写结构化、可维护程序的基础。本文将系统介绍函数的四个基本要素(返回类型、函数名、参数列表、函数体),深入剖析函数原型的作用,详细讲解形式参数与实际参数的绑定过程。
2026-03-14 21:52:57
407
原创 【C语言程序设计】第22篇:共用体与枚举类型
本文是C语言程序设计专栏的第二十二篇。在前几篇学习了结构体后,现在需要掌握两种与结构体密切相关但又各具特色的自定义类型——共用体和枚举。共用体允许在同一块内存区域存储不同类型的数据,但任意时刻只能使用其中一个成员,这种内存共享特性在节省空间和实现多类型处理时非常有用。枚举则为整型常量提供有意义的名称,使代码更清晰、更易维护。本文将系统介绍共用体的定义与内存共享特性,详细讲解枚举常量的定义方式及应用场景,并通过实例对比它们与结构体的区别。
2026-03-13 23:14:38
357
原创 【C语言程序设计】第21篇:结构体数组与内存对齐
本文是C语言程序设计专栏的第二十一篇。在上一篇学习了结构体的基本定义与使用后,现在需要掌握如何组织多个结构体数据——结构体数组,以及理解结构体在内存中的存储机制——内存对齐。结构体数组用于存储同类型的多条记录,是构建学生信息表、员工档案等应用的基础。内存对齐则是编译器为了提高CPU访问效率而采用的策略,它直接影响结构体的大小和内存布局。本文将系统介绍结构体数组的定义与遍历方法,深入剖析内存对齐的规则与成因,并通过实例展示如何优化结构体成员顺序以减少内存浪费。
2026-03-13 23:06:45
367
原创 【C语言程序设计】第20篇:结构体类型的定义与使用
本文是C语言程序设计专栏的第二十篇。在前几篇学习了数组后,我们掌握了如何存储相同类型的数据。但在实际问题中,经常需要将不同类型的数据组合在一起,比如学生的姓名(字符串)、年龄(整数)、成绩(浮点数)。C语言提供了结构体来实现这种需求。结构体是一种自定义的数据类型,允许我们将多个不同类型的成员组合成一个整体。本文将系统介绍结构体的定义语法、结构体变量的创建与初始化方法,详细讲解成员访问运算符.的使用,并通过结构体嵌套展示如何构建更复杂的数据结构。
2026-03-12 22:18:16
337
原创 【C语言程序设计】第19篇:字符数组与字符串处理
本文是C语言程序设计专栏的第十九篇。在前一篇学习了二维数组后,现在需要掌握C语言中一种特殊的数组——字符数组,以及建立在其基础上的字符串处理。C语言没有专门的字符串类型,字符串是以'\0'结尾的字符数组模拟的。理解这一本质,是正确使用字符串相关函数的基础。本文将系统介绍C语言字符串的本质与存储,详细讲解string.h库中strlen、strcpy、strcmp、strcat四个常用函数的实现原理与安全使用注意事项,并通过实例演示常见错误及防范方法。
2026-03-12 22:15:20
234
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅