原文章:
数据结构学习记录:第一章-绪论,以及一些知识前提 - 知乎 (zhihu.com)
此文章为作者本人搬运至这个网站。
说在前头:
各位在学习过程中,如果有任何不懂的地方,可以随时评论或者私信我!!!我每天都在高强度网上冲浪(这一点真的属实),从各位进行评论,到我发现评论,我认为应该最多不超过半个小时,所以啊,各位,尽情用你们的评论和私信淹没我吧!(=・ω・=)
绪论都是一些没什么用处还必须要有的一些“文言文”。而数据结构,以我简单来说,就是用一些算法来储存和管理一些计算机数据,其实就是增删改查,也可以说是更高阶一些的代码操作和写法。所以其不单独属于任何一种语言,因为其他语言也有自己的数据结构(应该吧),比如c语言和c++都有自己写数据结构的法子,我们这里是以c语言为基础来写的。
当然绪论中也有一些需要注意的知识前提:
1.抽象数据类型
抽象数据类型,简称为ADT,以及其后续的一系列有关的内容。图3这里是以一个三元组为示例来讲解的,也就是对某三个相同数据类型的数据的操作(比如int类型的1,2,3)
(顺带说明,我这里的图123的说法并不是一直不变的,也就是说我之后的图片也可能是图1或者图2等)
而这个内容不需要记住!!!只需要混个脸熟就行了,因为它的有关内容基本上都在图3,这里是讲解你可以用这个数据类型进行什么样的操作,在之后,那个第一行的Triplet可以变成List,就是线性表的内容,也可以变成Stack,就是栈的内容。而下面的 数据对象 和 数据关系 是给读者一个信息,也就是这个抽象数据类型三元组的数据都是什么样的(也就是用看似代码的方式展现,实则这些东西根本不会在代码中出现)。
而下面的这个 基本操作 可了不得!
看似有那么多函数可以直接用,实则根本不能用!
因为它们都仅仅是课本作者的一些示例罢了!
也就是说,如果你想要对这个三元组进行一些数据分析(比如找最大数,排序什么的),那么你就可以创建这些函数来实现!但是要怎么实现,还是要你自己写!
而这些函数的创建要在第12页才有写!
第12页,上半部分是函数的声明,下面才是函数的定义
第13页
而这里两张图片的内容其实也有一定门槛,里面看不懂的点可能会是typedef, Elemtype, *Triplet, Status, Triplet &T, return OK, exit(OVERFLOW), T = (ElemType *) malloc ( 3 * sizeof(ElemType);等等,我会逐一讲解,现在先往回看。
2.#define宏定义
这几个是比较重要的,因为之后的课本内容会频繁使用到他们。其中尤其要注意的就是:
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
这里是几个常见的状态宏定义,如果没有这些#define,那么这些OK,ERROR什么的在C语言中都毫无意义,也无法运行。
3.typedef
由于typedef是个大工程,如果各位有耐心的话可以先看看其他详细介绍typedef的相关文章:
C/C++ typedef用法详解(真的很详细)-CSDN博客
在这里我就是简单说一下吧:
简单来说,typedef语句可以来给已经定义好的数据类型起一个其他名字,并且可以用该其他名字定义数据。
如:
int n;
typedef int ElemType; //这里不需要加上 # 这个井号
ElemType num;
//在这里ElemType就可以用来定义int类型的数据,num就成了int类型的
//而上面的Status也就显而易见了,是由
typedef int Status;
//定义出来的
而这里的typedef int * Triplet;(我直接把ElemType换成int方便理解)
则是给Triplet用来定义int类型的指针,之后可以用
Triplet x;
来替代int *x;,即定义了一个指向int类型的指针变量。
下面的这些我会逐一讲解:
4.malloc动态分配内存函数
如果你已经知道malloc为何物,那么这一点就可以跳过了。
T = (ElemType * ) malloc (3 * sizeof(ElemType));
//第一个函数定义中的
//malloc函数需要用到#include <stdlib.h> 的库
//sizeof会输出该数据类型占用了几个字节
还是那句话,可以先看详细介绍的文章:
简单来说就是用typedef换名字定义的让Triplet来定义指向ElemType类型的指针T,来指向由malloc申请的 3乘以ElemType类型的字节数 大小的空间,T指向的即为该空间的头部位置,即保存的是该空间的首地址,这一方法常用来用变量来定义数组,具体可以看这个:
因为数组定义时不可以使用变量来定义长度,于是就可以用这个来定义。
而下面的那个
if (!T) exit(OVERFLOW);
/*这个其实是
if (!T){
exit(OVERFLOW);
}
的缩写,我想问就这么想省纸张吗= = */
/* OVERFLOW没有忘吧?刚刚学过的: #define OVERFLOW -2 */
也是显而易见的,如果T没有指到malloc分配的空间,或者由于内存爆满等原因malloc无法再申请空间了,那么 T就等于NULL,而 !NULL,就是非NULL,则if语句会成立。
而下面的那一句free(T); 则是释放这些malloc申请的空间,不必多说。
这样的话这几页的新东西就快讲完了,看上去很高大上,其实一点都不玄乎(因为更玄乎的在后面....),只要知道了malloc动态分配数组这回事儿就行了。
5.时间复杂度
时间复杂度是用来衡量代码运行时间的,每一个代码都有自己的时间复杂度,简记为O(f(n))。
往复杂了讲,可以看这个文章:
究竟什么是时间复杂度,怎么求时间复杂度,看这一篇就够了 - 知乎 (zhihu.com)
而简单了讲呢,就是O(1) < O(n) < O(n^2),而且一般来说时间复杂度越小越好,在一般情况下,当代码里面有一个n次的循环时,如:
for (int i = 0; i < n; i++){
}
这时候可以看作为O(n),而如果循环里面又有一个循环,如:
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
}
}
这时候可以说时间复杂度为O(n^2),显然运行时间比O(n)长,以此类推。
6.OJ
OJ,全称Online Judge System,即在线评测系统,是非常好用的代码测试处。OJ通常设有大量的题目,而且会有各种各样的测试数据来给你检测代码在各种情况下的可行性,而不需要你自己再进行手动输入测试了。而且你自己写的代码有可能在极大数量的数据测试下运行超时,亦或者是答案格式不对,亦或者是内存溢出等等这些你不易察觉到的问题,OJ都可以帮你测试出来。
在这里我推荐几个常见的OJ平台:
1.力扣(leetcode):
非常有名的编程平台,里面众多大佬云集,也有论坛。
缺点就是难度偏高,而且有些地方可能还要VIP。
2.洛谷:
界面比较简洁,没有杂七杂八的东西,很方便找到刷题的地方。
缺点就是测试的时候不告诉你测试用例是什么,也就是说你可能就算提交到这里也不知道具体错在哪里。
3.牛客网:
牛客网 - 找工作神器|笔试题库|面试经验|实习招聘内推,求职就业一站解决_牛客网
这个网站应该是更偏向于找工作的编程网,而它的OJ有一点就是可以进行断点调试,不过我也没用过不知道怎么样。
缺点也很明显,倾向于找工作的网站对于我们初学者估计不太适合,而且这里也同样没有公开测试用例。
4.PTA
这个是我们数据结构老师用来发布作业的平台,好像是浙江大学的官方OJ,据我个人的使用体验来说还是蛮好的,它可以记录你之前提交的结果,而且各种测试用例会给出提示(我们的作业里面就有,不过好像官方的作业就没有),里面的题我个人感觉还是挺适合初学者的。而且比较干净没有广告(毕竟是和大学相结合的)。
缺点那就是没有讨论区,如果自己在这里学习的话也不知道其他人的情况。
5.自己大学的acmOJ平台
一般理工科大学如果有acm团队的话,那么应该就会有自己的OJ平台(比较厉害的大学应该都有),这个具体可以问问自己所在大学的学长学姐有没有相关的校园OJ平台,不过学校自己搭建的平台多半比较简陋,所以只能是个参考吧。
至此,第一章应该就到这里了。