
数据结构理论知识
文章平均质量分 71
数据结构的理论武装
赔罪
合作私聊 有偿解决计算机问题
展开
-
矩阵的介绍及乘法运算(附C语言实现代码)
这m×n 个数称为矩阵A的元素,简称为元,数aij位于矩阵A的第i行第j列,称为矩阵A的(i,j)元,以数 aij为(i,j)元的矩阵可记为(aij)或(aij)m × n,m×n矩阵A也记作Amn。注意:矩阵的概念很多,而且矩阵的运算属于计算机图形学,数学等学科的必备知识,其如果要完全写下来则完全可以写出一本书,本文知识简单介绍,矩阵的基本知识必备要了解加减乘除,其中以乘法在计算机中又使用众多。由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。原创 2025-05-02 07:00:00 · 214 阅读 · 0 评论 -
用数组实现模拟算法C/C++实现
数组这个概念并不陌生,然而,数组本身也是一种数据结构。数组在存储数据时是按顺序存储的,存储数据的内存也是连续的,所以他的特点就是寻址读取数据比较容易,插入和删除比较困难。简单解释一下为什么,在读取数据时,只需要告诉数组要从哪个位置(索引)取数据就可以了,数组会直接把你想要的位置的数据取出来给你。插入和删除比较困难是因为这些存储数据的内存是连续的,要插入和删除就需要变更整个数组中的数据的位置。所以数组对比链表,数组读取和使用更加灵活,而链表插入和删除更加便捷。原创 2025-05-02 07:00:00 · 330 阅读 · 0 评论 -
C++中string字符串类型介绍
C语言中通过字符相连已经基本创造出了字符串的常规操作,然而,字符串在C语言中并不是常规类型,而是一个类似于数组的结构,在C++中,通过模板类的操作创建了。原创 2025-05-01 18:51:04 · 334 阅读 · 0 评论 -
字符串的KMP算法详解及C/C++代码实现
紧接上文,我们知道了暴力匹配的算法在时间运行上的缺陷,假设字符串T的长度为n,字符串P的长度为m,则整个算法的时间复杂度为O( n * m ),而对于一个复杂的现实情况而言 n >> m >> 2 (即n远远大于m,m远远大于常数),这样的计算计算机的负担很重。请思考一个暴力匹配的情况:给定一个主字符串T = “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB”(47位)同时给定模式串 P = “AAAAAB”(6位)原创 2025-05-01 18:45:51 · 378 阅读 · 0 评论 -
C++字符串常用操作(二)
这并不是最理想的算法,但却这是字符串匹配算法中最容易理解的算法,算法核心为给定一个主串T和一个模式串P,求问是否P是属于T的一个字串,如:”Hello”中”llo”就是其中的一个字串,对于暴力匹配算法而言,我们可以利用两层循环进行比对,第一层循环中找寻T字符串中的每一个字符,第二层循环找寻的是每一个P字符,进入第二层循环时T字符串也会跟着进行字符前进,如果发生不匹配则产生一个回溯回到第一层循环的进入字符的下一个字符。输出Welcome Hello My CSDN.com。原创 2025-04-29 18:40:59 · 293 阅读 · 0 评论 -
C++字符串常用操作(一)
在程序设计中,字符串操作是必不可缺的,无论是工程设计还是算法设计均离不开字符串,字符串是由一个个单独的字符构成的串,其数据结构是线性的,常以ASCII码表示,同时只要设定得当,其展示任何一种编码也都是可以的。字符串有很多的操作,也有非常多的扩展算法,本文从设计的角度介绍这些基本的字符串操作以及其实现代码,本文实现的大多数代码诸如C和C++中的头文件<string.h>(C++则是<cstring>)已经封装好了相应的函数和方法可以直接使用。原创 2025-04-29 18:38:49 · 439 阅读 · 0 评论 -
C++STL之Map容器
也是一种关联容器,它是 键—值对的集合,即它的存储都是以一对键和值进行存储的,Map通常也可以理解为关联数组(associative array),就是每一个值都有一个键与值一一对应,因此,map也是不允许重复元素出现的。同时map也具备set的相关功能,其底层也会将元素进行自动排序。原创 2025-04-27 19:42:45 · 475 阅读 · 0 评论 -
set theory(集合论)
集合论,是数学的一个基本的分支学科,研究对象是一般集合。集合论在数学中占有一个独特的地位,它的基本概念已渗透到数学的所有领域。集合论或集论是研究集合(由一堆抽象物件构成的整体)的数学理论,包含了集合、元素和成员关系等最基本的数学概念。在我们还在高中教育阶段,可能或多或少会接触到一些诸如集合并交差的运算,而集合论与我们C++的STL运算有很多相似而相同的关系。原创 2025-04-27 19:37:07 · 523 阅读 · 0 评论 -
C++STL之Set容器
Set集合的底层使用一颗红黑树(可能读者对此不太了解,等但学到树论与图论的章节的时候就会明白原因),其属于一种非线性的数据结构,每一次插入数据都会自动进行排序,注意,不是需要排序时再排序,而是每一次插入数据的时候其都会自动进行排序。这也是前文学过的标准用法,接下来,让我们了解一个更加先进和便捷的方法,auto方法迭代,这需要我们编译器开启C11标准,每个编译器的开启标准不一,请具体情况具体分析。Set的性质有:数据自动进行排序且数据唯一,是一种集合元素,允许进行数学上的集合相关的操作。原创 2025-04-27 19:31:41 · 351 阅读 · 0 评论 -
C++STL之Priority_queue(优先队列)
优先队列是一种极其特殊的队列,他与标准的队列使用线性结构进行计算不同,优先队列的底层是以散列的状态(非线性)表现的,他与标准的队列有如下的区别,标准的队列遵从严格的先进先出,优先队列并不遵从标准的先进先出,而是对每一个数据赋予一个权值,根据当前队列权值的状态进行排序,使得权值最大(或最小)的永远排在队列的最前面。原创 2025-04-23 12:39:21 · 389 阅读 · 0 评论 -
C++STL之Queue容器
回顾一下之前所学的队列,队列和栈不同,队列是一种先进先出的数据结构,STL的队列内容极其重要,虽然内容较少但是请务必掌握,STL的队列是快速构建搜索算法以及相关的数论图论的状态存储的基础。标准的队列创建方法是直接创建空队列再进行其他的操作,由于队列的特殊性质,拥有其他容器的参数可以这样创建,这种多参数的方式可能有一些复杂,一般也很少这样使用。访问对头元素,可以返回其数值,也可以进行相应的操作,这里更加建议多使用front()访问队头数据,因为我们进行出队操作均是从队头进行出队的。访问队尾元素,较为少用。原创 2025-04-23 12:33:45 · 295 阅读 · 0 评论 -
C++STL之stack栈容器
回顾一下之前所学的栈,栈是一种先进后出的数据结构,而实现方式需要创建多个结构体,通过链式的方式进行实现,这是标准的栈的思路,而在STL中栈可以以更为简单的方式实现。头文件 #include<stack>格式为:explicit stack (const container_type& ctnr = container_type());我们以int类型作为参数为例进行创建,其创建方法与vector无异。原创 2025-04-22 11:09:54 · 405 阅读 · 0 评论 -
算法复杂度
算法复杂度(Algorithm complexity):在问题的输入规模为 nn 的条件下,程序的时间使用情况和空间使用情况。「算法分析」的目的在于改进算法。正如上文中所提到的那样:算法所追求的就是所需运行时间更少(时间复杂度更低)占用内存空间更小(空间复杂度更低)。所以进行「算法分析」,就是从运行时间情况、空间使用情况两方面对算法进行分析。事后统计:将两个算法各编写一个可执行程序,交给计算机执行,记录下各自的运行时间和占用存储空间的实际大小,从中挑选出最好的算法。预先估算。原创 2025-04-21 19:23:00 · 890 阅读 · 0 评论 -
数据结构与算法
数据结构可以分为「逻辑结构」和「物理结构」。集合结构线性结构树形结构图形结构。顺序存储结构链式存储结构。「逻辑结构」指的是数据之间的关系,「物理结构」指的是这种关系在计算机中的表现形式。例如:线性表中的「栈」,其数据元素之间的关系是一对一的,除头和尾结点之外的每个结点都有唯一的前驱和唯一的后继,这体现的是逻辑结构。而对于栈中的结点来说,可以使用顺序存储(也就是顺序栈)的方式存储在计算机中,其结构在计算机中的表现形式就是一段连续的存储空间,栈中每个结点和它的前驱结点、后继结点在物理上都是相邻的。原创 2025-04-21 13:00:46 · 804 阅读 · 0 评论 -
C++STL之List容器
List链表的概念再度出现了,作为线性表的一员,C++的STL提供了快速进行构建的方法,为此,在前文的基础上通过STL进行直接使用,这对于程序设计中快速构建原型是相当有必要的,这里的STL链表是单链表的形式。头文件:#include<list>格式为:explicit list (const allocator_type& alloc = allocator_type());我们以int类型作为参数为例进行创建,其创建方法与vector无异。原创 2025-04-20 18:47:17 · 510 阅读 · 0 评论 -
C++STL之Vector容器
Vector可以翻译为向量,或向量数组,至于为什么以向量命名,可以理解为一维空间也是存在向量的。Vector是最简单的序列是容器,就像数组一样,向量使用连续的存储位置作为元素,这意味着它们的元素也可以使用常量指向其元素的偏移来访问,与数组一样有效。但与数组不同,它们的大小可以动态变化,其存储由容器自动处理。总结一下头文件:#include <vector>格式为:vector<Data_Types> name;我们以Int类型作为参数为例,进行创建。原创 2025-04-20 18:42:45 · 579 阅读 · 0 评论 -
C++STL教程入门
在上一篇文章我们已经基本的了解了什么是C++的STL(标准模板库),在本章中绝大多数内容都是在介绍常用的STL模板的使用以及其一些参数的介绍,但是请注意,STL由于其设计之初就容纳了大量的程序员思维结晶,经过了无数次的讨论才形成了一个统一的标准,他同时拥有大量的内容和知识点,如果完全讲解内容,展开完完全全可以写出一本500页的书,本篇还是以数据结构为主,因此,这里只是略讲,而且还主要是略讲与数据结构相关的容器,不是深入讲解。在这里引用本人的一位老师说的话:不学STL的C++是不完整的C++。原创 2025-04-20 18:35:45 · 335 阅读 · 0 评论 -
C与C++的区别
1980年,Bjarne Stroustrup博士着手创建一种新的语言,能够具有面向对象的程序设计特色。在当时,面向对象编程是一个新颖的概念,Stroustrup博士并不是从头开始设计新语言,而是使用C语言进行修改,而这就是C++语言。原创 2025-04-20 18:34:23 · 538 阅读 · 0 评论 -
循环队列的基本操作及C语言代码实现
我们初始化相比链表而言更为简单了,核心就在于申请空间以及将front指针和rear指针内容赋值为0,即指向第0个元素即可(注意第 0个元素内容为空)。原创 2025-04-20 18:31:17 · 638 阅读 · 0 评论 -
循环队列及假溢出的现象图文详解
我们已经明白了队列这种基本数据结构,对于顺序队列而言,其存在已经足够解决大多时候的设计问题了,但是其依旧存在一些缺陷和不足,因为我们的入队和出队操作均是直接在其后面进行结点的链接和删除,这就造成其使用空间不断向出队的那一边偏移,产生假溢出。什么是假溢出?原创 2025-04-20 18:22:50 · 439 阅读 · 0 评论 -
顺序队列的基本操作(入队出队遍历)及C/C++代码实现
如图,进行入队(push)操作的时候,我们首先需要特判一下队列是否为空,如果队列为空的话,需要将头指针和尾指针一同指向第一个结点,即front=n;rear=n。当如果队列不为空的时候,我们只需要将尾结点向后移动,通过不断移动next指针指向新的结点构成队列即可。原创 2025-04-20 18:18:48 · 372 阅读 · 0 评论 -
顺序队列的介绍及C/C++代码实现
在开始前,请牢记这句话:队列是一个先进先出的数据结构。队列(queue)是限定在表的一端进行插入,表的另一端进行删除的数据结构,如同栈的学习,请联系前文所学链表,试想一个单链表,我们只能对他的链表表尾进行插入,而只能对链表的表头进行结点的删除,其余一切的操作均不允许,这样强限制性的“链表“,就是我们所说的队列。如图:队列就像一个两端相通的水管,只允许一端插入,另一端取出,先放入管中的球先从管中拿出。原创 2025-04-20 18:13:49 · 428 阅读 · 0 评论 -
栈数组与栈链表C语言代码实现
PS:栈的概念被极大量的运用于各种程序设计之中,作为一种数据结构,其先进后出的特殊性质为很多算法的设计埋下伏笔,为之开通快车道。原创 2025-04-15 12:07:47 · 238 阅读 · 0 评论 -
栈的基本操作及C语言代码实现
如图:出栈(pop)操作,是在栈不为空的情况下(注意一定要进行判空操作),将栈顶的元素删除,同时top指针,next向下进行移动即可的操作。原创 2025-04-15 12:05:58 · 242 阅读 · 0 评论 -
栈(先进后出的数据结构)的设计与实现
如图:栈就像一个放球的单管桶,只允许球从桶的开口这一端取出,并且球先放入桶中则后从桶中拿出。原创 2025-04-14 22:19:43 · 473 阅读 · 0 评论 -
循环链表的基本操作及C语言代码实现
与普通的单链表和双向链表的遍历不同,循环链表需要进行结点的特判,找到尾节点的位置,由于尾节点的next指针是指向头结点的,所以不能使用链表本身是否为空(NULL)的方法进行简单的循环判断,我们需要通过判断结点的next指针是否等于头结点的方式进行是否完成循环的判断。如图,对于插入数据的操作,基本与单链表的插入操作相同,我们可以创建一个独立的结点,通过将需要插入的结点的上一个结点的next指针指向该节点,再由需要插入的结点的next指针指向下一个结点的方式完成插入操作。原创 2025-04-14 22:13:55 · 444 阅读 · 0 评论 -
循环链表的介绍及创建(C语言代码实现)
如同单链表的创建,我们需要先创建一个头结点并且给其开辟内存空间,但与单链表不同的是,我们需要在开辟内存空间成功之后将头结点的next指向head自身,我们可以创建一个init函数来完成这件事情,为了以后的重复创建和插入,我们可以考虑在init重创建的结点next指向空,而在主函数调用创建之后手动讲head头结点的next指针指向自身。next表示指针,它永远指向自身的下一个结点,对于只有一个结点的存在,这个next指针则永远指向自身,对于一个链表的尾部结点,next永远指向开头。在主函数重调用可以是这样。原创 2025-04-12 08:00:00 · 480 阅读 · 0 评论 -
双向链表的基本操作及C语言代码实现
如图所示:对于每一次的双向链表的插入操作,我们首先需要创建一个独立的结点并通过malloc操作开辟相应的空间,其次我们选中这个新创建的独立节点,将其的pre指针指向所需插入位置的前一个结点,同时,其所需插入的前一个结点的next指针修改指向为该新的结点,同理,该新的结点的next指针将会指向一个原本的下一个结点,而修改下一个结点的pre指针为指向新结点自身,这样的一个操作我们称之为双向链表的插入操作。原创 2025-04-12 08:00:00 · 281 阅读 · 0 评论 -
双向链表的基本设计(C语言代码实现)
单链表在很多时候已经可以胜任很多优秀的操作了,但是,单链表任然存在不足,所谓‘单链表’,是指结点中只有一个指向其后继的指针,具有单向性,有时需要搜索大量数据的时候,就必须要多次进行从头开始的遍历,这样的搜索不是很便利。对于逐步添加数据,我们采取的做法是,开辟一段新的内存空间作为新的结点,为这个结点进行的data进行赋值,然后将已成链表的上一个结点的next指针指向自身,自身的pre指针指向上一个结点。next代表的是后继指针,它永远指向当前结点的下一个结点,注意,如果当前结点是尾结点,则next指针为空。原创 2025-04-11 17:20:04 · 228 阅读 · 0 评论 -
单链表的基本操作及C语言代码实现
的概念想必大家都不会陌生,即就是从链表的头开始,逐步向后进行每一个元素的访问,这就是遍历,对于遍历操作,我们可以衍生出很多常用的数据操作,比如说查询元素,修改元素,获取元素个数,打印整个链表数据等等。删除元素要建立一个前驱结点和一个当前结点,当找到了我们需要删除的数据时,直接使用前驱结点跳过要删除的结点指向要删除结点的后一个结点,再将原有的结点通过free函数释放掉。进行遍历的思路极其简单,只需要建立一个指向链表L的结点,然后沿着链表L逐个向后搜索即可。原创 2025-04-11 08:00:00 · 302 阅读 · 0 评论 -
单链表的基本设计(C语言代码实现)
单链表是一种链式存取的数据结构,,链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示的线性表称作线性链表(单链表),单链表是链式存取的结构。对于链表的每一个结点,我们使用结构体()进行设计,其主要内容有:其中,DATA数据元素,可以为你想要储存的任何数据格式,可以是数组,可以是int,甚至可以是结构体(这就是传说中的结构体套结构体)原创 2025-04-11 08:00:00 · 778 阅读 · 0 评论 -
链表-顺序存储和链式存储
C语言使用中,由于以上出现的这些问题,我们链表的概念就应运而生,链表通过不连续的储存方式,以及指针的灵活使用,巧妙的简化了上诉的内容,同时链表是自适应内存大小的,也就是说无论我们设多大的数据,理论上都可以实现(当然不能超过你的机器承载),注意,有许多较晚的语言通过底层的方式解决了数组插入和删除时的时间浪费,如PYTHON。其中DATA为自定义的数据类型,可以是简单的int型,也可以是复杂的struct结构体类型,而NEXT为指向下一个链表结点的指针,通过访问NEXT,可以引导我们去访问链表的下一个结点。原创 2025-04-10 08:00:00 · 293 阅读 · 0 评论 -
数据结构入门-程序运行时的内存与地址
由这个图可以清晰的发现对于每一段的内存中的数据,都有一个地址与之相对应,也真是因为有地址的存在,我们计算机中才可以轻易的去访问到其中数据,拿一个数组来说,数组在C语言中是顺序存储的,因此,如上图的数据直接用代码找到其数据以及地址的话可以这样写。不难察觉,指针似乎与内存的联系十分密切,事实上,指针就是为了灵活的操纵内存而设计的, C/C++语言的灵魂就在指针上,指针的存在,使得内存地址可以像数据一样进行赋值修改,极其灵活且方便(同时也具有风险)。(地址的常用表示为十六进制表示法,即Ox+十六进制数)原创 2025-04-10 08:00:00 · 660 阅读 · 0 评论