第1章 绪论
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论
概述
第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语。对于这些概念术语,我个人不推崇死记硬背,记住了当然好,记不住也没关系,但是一定要做到完全理解。就算嘴上说不出来,心里也一定要明白这个过程的含义。
数据结构
数据(data)是对客观事物的符号表示。在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素(data element)是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据对象(data object)是性质相同的数据元素的集合,是数据的一个子集。
数据结构(data structure)又称逻辑结构,是相互之间存在一种或多种特定关系的数据元素的集合。通常有以下四类基本结构:集合、线性结构、树形结构、图状结构或网状结构。
存储结构(物理结构)是数据结构在计算机中的表示(又称映像)。
数据类型(data type)是一个值的集合和定义在这个值集上的一组操作的总称。
抽象数据类型(AbstractData Type)是指一个数学模型以及定义在该模型上的一组操作,可细分为:原子类型、固定聚合类型、可变聚合类型。
算法
算法与数据结构密不可分,算法往往是建立在特定数据结构之上的。
一个算法有5个重要特性:有穷性、确定性、可行性、输入、输出。
而衡量一个算法是否优秀,则主要从以下几点考虑:正确性,可读性,健壮性,时间复杂度,空间复杂度。
其他
除了对数据结构和算法的简单介绍,本章还预定义了一些会被频繁使用的常量与类型,见下图所示的Status.h文件。
另外,为了之后测试数据方便,我自定义了一个从文件中读取数据的函数Scanf,使用格式与fscanf类同。
源码
文件一 ☛ Status.h
文件二 ☛ Scanf.c
第2章 线性表 - 单链表顺序存储结构
——《数据结构》-严蔚敏.吴伟民版
本源码引入的文件 链接☛ Status.h
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\01 SequenceList
概述
数据结构的学习当然要从线性表学起,而线性表里首先需要学习单链表,这里从单链表最简单的顺序存储结构(本质就是可变数组存储)开始。
解析
单链表强调元素在逻辑上紧密相邻,所以首先想到用数组存储。但是普通数组有着无法克服的容量限制,在不知道输入有多少的情况下,很难确定出一个合适的容量。对此,一个较好的解决方案就是使用动态数组。首先用malloc申请一块拥有指定初始容量的内存,这块内存用作存储单链表元素,当录入的内容不断增加,以至于超出了初始容量时,就用calloc扩展内存容量,这样就做到了既不浪费内存,又可以让单链表容量随输入的增加而自适应大小。
单链表顺序存储结构如下图:
可能涉及到的语法难点
刚接触数据结构的同学,单链表顺序存储结构可能会是其面对的第一个坎。这里涉及到了结构体、动态数组、结构指针,甚至还有函数变量(函数做参数,本质是函数指针),所以需要有相对扎实的语言语法基础。当然,这也并不是说一定得掌握了高级语法才能开始学习数据结构,可以先将语言学到入门(入门意味着学会了提问),再边学数据结构边巩固语法。一定要亲自动手写一写,否则,肯定学不好。
源码
文件一 ☛ SequenceList.h
文件二 ☛ SequenceList.c
文件三 ☛ SequenceList-main.c (测试文档)
测试结果展示
第2章 线性表 - 求并集A=A∪B
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ SequenceList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\02 Union
概述
求并集A=AUB是数学集合中最常用的操作之一。
解析
求并集的思路很简单,大致可分为三步:
第一:找到A的链表尾部;
第二:开始遍历B,判断B的每个元素是否在A中存在;
第三:如果B中元素不在A中,则将其插入到A中,并继续向前探索,直至遍历完B中全部元素。
可能涉及到的语法难点
通过这个小示例。进一步体会多函数协作的优点。把不同功能的函数分开写,把不同职责的文件分开写,有利于程序的可读性与健壮性。
源码
文件一 ☛ Union.h
文件二 ☛ Union.c
文件三 ☛ Union-main.c (测试文档)
测试结果展示
第2章 线性表 - 归并单链表(顺序表)
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ SequenceList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\03 MergeSqList
概述
单链表(顺序表)归并算法,将两个顺序表合并到一个新的顺序表中,要求合并前后顺序表均有序排列。
解析
顺序表的归并有两种方案,一种使用指针,另一种利用数组下标实现。两种方案都还是通过调用单链表顺序存储结构中封装的各个函数的来实现的,理解上并无难度。
源码
文件一 ☛ MergeSqList.h
文件二 ☛ MergeSqList.c
文件三 ☛ MergeSqList-main.c (测试文档)
测试结果展示
第2章 线性表 - 单链表链式存储
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\04 SinglyLinkedList
概述
比起之前顺序存储的单链表,链式存储有很多优点,比如删除与插入更方便,不用来回移动大量元素。但与此对应的是存取指定位置元素时将变得费劲,因为顺序存储结构中,通过数组下标就可以获取第i个元素,但是在链式存储中,必须由头指针或尾指针(如果有的话)开始遍历整个链表直至寻找到需要的元素。在元素的查找效率方面,此两种存储结构无明显差异。
解析
单链表链式存储结构引入了链表的概念,链表由一个个小的结点组成,每个结点都包含一个数据域和指针域,指针域指向的是紧邻的下一个结点,最后一个结点指针通常为NULL。如果将最后一个结点的指针指向开头,那么这个链表就成了循环单链表。
值得注意的是,这儿所示的链表都是有头结点的单链表。有头结点意味着头结点指针指向的结点数据域为空,头结点的存在仅仅是作为标记单链表的开始,有头结点的单链表在操作时更加方便,不用专门为头结点的增删情况写额外代码,这一点可以在实际应用中加以体会。
单链表链式结构如下图:
可能涉及到的语法难点
单链表链式存储也用到了动态分配内存。值得注意的是,由于头结点的指针本身就是个结构指针,所以在初始化、创建、销毁等需要改变头结点指针的地方,则要注意函数形参为二级指针,即指向头指针的指针。新手很容易犯的错误是该用二级指针的地方使用了一级指针,这样做的后果就是明明函数内分配了所需内存,但是外面却访问不到,也可能明明函数内销毁掉的内存,外面还可以访问到。这样不仅会引起内存访问差错,甚至会引起程序崩溃,所以,这一点很值得引起重视。
源码
文件一 ☛ SinglyLinkedList.h
文件二 ☛ SinglyLinkedList.c
文件三 ☛ SinglyLinkedList-main.c (测试文档)
文件四 ☛ TestData_HL.txt (头插法数据文档)
文件五 ☛ TestData_TL.txt (尾插法数据文档)
测试结果展示
第2章 线性表 - 归并单链表(链式存储)
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ SinglyLinkedList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\05 MergeList
概述
链式单链表的归并,与归并顺序存储的单链表算法思想一致。
解析
归并单链表时会涉及到插入操作。在顺序存储的单链表里,插入一个元素意味着要将插入点之后的元素整体后移。但是在链式存储的单链表里,只需改变插入点附近的指针即可,节省了大量时间。
链式存储的单链表插入一个元素的方式如下图:
源码
文件一 ☛ MergeList.h
文件二 ☛ MergeList.c
文件三 ☛ MergeList-main.c (测试文档)
文件四 ☛ TestData_HL.txt (头插法数据文档)
文件五 ☛ TestData_TL.txt (尾插法数据文档)
测试结果展示
第2章 线性表 - 静态链表
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ Status.h
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\06 StaticLinkedList
概述
静态链表用数组存放数据,存取方式模拟了系统的malloc分配和free回收机制。
解析
在《数据结构》原书中,对静态链表的表述是有些复杂的,这里对其进行了适当简化,但中心思想不变。
静态链表是特殊的顺序表,它从数组(一块连续的内存)中孕育,但行为却类似于单链表,它反映出了链式单链表在系统中实现的本质。静态链表依靠自身的一个游标来实现单链表中结构指针的作用,所以,在存取元素时,一方面要考虑静态链表内部的游标变动,另一方面也要考虑整个空间中剩余内存的游标变化,因为整个内存块同样也是通过游标来链接的。
静态链表存储结构及存取机制如下图:
可能涉及到的语法难点
灵活应用typedef来创造新类型,比如在静态空间SPACE定义时,将整个结构数组看做了一个新的类型Component。
源码
文件一 ☛ StaticLinkedList.h
文件二 ☛ StaticLinkedList.c
文件三 ☛ StaticLinkedList-main.c (测试文档)
测试结果展示
第2章 线性表 - 集合运算(A-B)∪(B-A)
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ Scanf.c、StaticLinkedList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\07 Difference
概述
利用静态链表求集合(A-B)∪(B-A)。
解析
思路很简单,先建立包含集合A中元素的静态链表,然后遍历集合B,若B中元素不在A中,将其加入静态链表,否则,将其从静态链表中删掉,注意头、尾指针的修改。
源码
文件一 ☛ Difference.h
文件二 ☛ Difference.c
文件三 ☛ Difference-main.c (测试文档)
文件四 ☛ TestData.txt (集合A和B的数据文档)
测试结果展示
第2章 线性表 - 双循环链表链式存储
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ Status.h
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\08 DualCycleLinkedList
概述
双循环链表就是头尾相连,并且每一个结点都可以指向它的前驱和后继的链表。
解析
双循环链表解决了单链表无法回溯的问题,即在双循环链表中,从任一结点出发都可以顺序或者逆序遍历完整个链表。双循环链表的操作中,插入和删除较为重要,要注意改变各指针指向时的次序。另外要特别留意头、尾结点指针的改变。
双链表插入、删除如下图:
源码
文件一 ☛ DualCycleLinkedList.h
文件二 ☛ DualCycleLinkedList.c
文件三 ☛ DualCycleLinkedList-main.c (测试文档)
测试结果展示
第2章 线性表 - 扩展的线性单链表
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\09 ExtenLinkedList
概述
扩展的线性单链表即在普通的单链表上增设了尾指针,并保存了链表的长度。
解析
扩展的线性单链表重新定义了单链表,并增设了一系列常用操作,如DelFirst、Append、Remove等函数。此处的线性单链表只是对原单链表数据域和操作集的扩充,其链表本质并无变化。
源码
文件一 ☛ ExtenLinkedList.h
文件二 ☛ ExtenLinkedList.c
文件三 ☛ ExtenLinkedList-main.c (测试文档)
测试结果展示
第2章 线性表 - 归并扩展的线性链表
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ ExtenLinkedList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\10 MergeEList
概述
依然是线性表归并算法,不过这次归并的是经过扩展的线性表。
解析
本次归并应用的都是扩展的线性表里的操作,使整个归并算法更加高效。
源码
文件一 ☛ MergeEList.h
文件二 ☛ MergeEList.c
文件三 ☛ MergeEList-main.c (测试文档)
文件四 ☛ TestData_La.txt (线性单链表La数据文件)
文件五 ☛ TestData_Lb.txt (线性单链表Lb数据文件)
测试结果展示
第2章 线性表 - 一元多项式运算
——《数据结构》-严蔚敏.吴伟民版
★有疑问先阅读★
源码使用说明 链接☛☛☛ 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明
课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑
习题集全解析 链接☛☛☛ 《数据结构题集》习题解析合辑
本源码引入的文件 链接☛ ExtenLinkedList.c
文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲02 线性表\11 Polynomial
概述
一元多项式的运算,采用的存储结构是扩展的线性表。
解析
一元多项式的运算本质是对扩展的线性表进行插入,删除操作,理解上并无难度,遇到想不通的地方,可以画示意图辅助理解。