兄弟们,我又来了。今天我们来谈一谈顺序表。我们应该知道顺序表是属于数据结构的,那么什么是数据结构呢,首先数据结构,一定要有数据吧,但是这些数据的排列方式,就是数据结构。就比如,你养了一群鸭子,你想要数一数有多少只鸭子,你就要小鸭子排队,对不起鸭。那你就可以用一间房子,里面有一个一个的小笼子,一只鸭子放一个笼子,是不是数笼子就行了。像这样就是把一个一个的数据分装到一个一个的空间。这个就有利于管理。然后我们再把这个笼子编一个号,那么我们就可以精准的查找一只鸭子(有人就说了,有什么事要精准的找鸭子啊,如果你非要这样说的话,我想你可以换一种叫法,这个数据是用户信息,这个就要精准的找了吧,但凡找错了,就是冤假错案),而找到了他,我们就可以对他做一系列的事(增删查改)
那么什么是顺序表呢。我们也没有什么高端的说法就是按名字来嘛!但是我们需要先假想一些数据把他们按顺序排列起来的那个表,不就是叫顺序表嘛。(而在此之前温馨提示这个是线性表)
顺序表向下分为静态顺序表和动态顺序表,静态顺序表就像一个数组,还不是可变数组,是一个定长数组,因此他有一个致命的缺点就是不知道开多大空间,大了就浪费,小了就不够。你再想,一个公司是不是都是从小公司一步一步走来的,因此静态的缺点就出来了,一个小公司需要开像大公司一样的空间吗,所以我们不看这个,我们看动态顺序表。
但是我个人感觉这个动态也没有动的很厉害,但是比起静态来说还是好的多。
你想象你创建了一个int类型的数组,假设一开始有4个元素的空间(不是一开始就装了4个元素)然后你往里面写数据当你写了4个的时候是不是就写不下了。那么这时我们就开始realloc空间,但是我们要开多大呢,我们有一个2倍开辟法,原理是
总结就是2倍效率高。所以我们假如买手机什么的电子产品你看内存是不是都是128G,然后就是256G,512G。
现在开始我们就已经具备了写顺序表的能力了。但是我们还是从简单开始讲,首先,顺序表有3个最最最最基本的3个元素,一个可以记录这个顺序表一共有多少个元素的类型(一般是int,二班你随意),最后一个是记录开辟了多大空间的类型,最后一个就是一个记录数据的是一个指针,这个指针的什么类型的指针看你自己,为什么我们要指针呢,而不是给一个数组就行了。你想如果给了一个数组给你,我还要这个顺序表干嘛,直接一个数组不是全部搞定了(这个就是脱裤子放屁),所以我们不难给数组,我们给指针,指向一个空间,这个空间可以随我们造,而且这个空间也没有限定有多大,但是你不能搞一个你内存都没这么大的空间,你这样搞,你不报错,谁报错。这个时候就看你动态内存管理有没有学好了(你说没学过,我又没发这种文章,为了你不去看别人的,我就勉为其难告诉你,创建用malloc,修改用realloc就行了,这两个可以把别人的功能大部分包含进去)所以我们现在有3个变量(类型不同),是不是就要用结构体了把他们合并啊,就是这样
SLDataType这个是我自己定义的一个类型,我可以让他随时变为任何类型,那为什么要这样设计呢(首先你要知道每一个设计的背后都有一个吃亏的人,你知道一个晚上老板要换类型,成百上千个类型,要我一个一个的手改,不是我是我朋友,是一种多么痛苦的事吗,啊啊啊啊)兄弟们,你最好记到不然下次你碰到的时候,朋友不会同情只会发朋友圈来安慰你。
现在就是向通讯录的过度了。首先,我们先说指向一个数组的指针,假如这个数组是int,内存种就
对不对,我们的每一个元素,就是int,我们可以存其他的类型吗,可以啊,char,float,但是我们可以结构体吗,还真可以。但是我们还是不会用数组(脱裤子放屁了 ),所以我们还是用指针,我们用一个指向结构体的指针,而这个结构体就是我们的联系人信息(电话,年龄,名字,地址),所以我们先建立一个结构体,
然后我们再把这个类型设为指针的类型,对不对,对就错了。你想一想,你想不想改类型改一个晚上,所以我们要新建一个关键字来代表这个类型
下面就开始写程序了。
我们要明确一点,我们要写通讯录,怎么开这个头呢。有思路吗。嗯,没。那没思路的时候,我给你们提供一个万能的思路,就是想一个我们熟悉的东西,但是和他很类似。我们想那个东西我们是怎么开头的,以及后面的过程。所以你们现在可以想到什么呢和通讯录类似,细心的小伙伴可能就可以发现,我前面一直在拿通讯录(顺序表)和数组做对比。所以我们就可以用数组来对比通讯录。
所以我们想数组是怎么用是,首先数组我们要用的话是不是要先定义出来,所以我们就知道了通讯录我们需要先定义出来,数组我们定义出来了是不是就可以使用了,使用后面就是我们的增删查改,但是不同的是数组我们计算机会在程序执行完后自动销毁,但是通讯录需要我们手动销毁
总结就是我们通讯录主要分为3步一,初始化。二,主要功能实现。三,销毁。
开始我们的表演
一,初始化
我们要初始化就要先观察他里面要什么样的元素,才好初始化对不对。你我们就来看,
有人就会说为什么看这个,不是还有一个struct吗,你想那个是数据的内容而我们在什么时候才要初始化数据的内容呢,是不是我们写录数据的时候,那为什么要初始化这个struct呢。因为这个SeqList如果你仔细看的话就可以发现,我的数据是存不了的,你看这里面那个类型可以存数据,有人说指针啊,指向了一个地方,不就可以存放了吗,看到这里应该知道了吧。这个指针虽然指向了一个地方,但是计算机没有为他分配空间啊,所以我们初始化的目的就出来了,就是为他开辟一个空间,一般来说为4个单位。我们看下面的类型,一个是内容的个数,一个是开辟空间可以存放的内容个数。我们在后面加数据的时候,对这两个数要进行相应的操作。如果你不想操作一个随机数的话,就先给他赋一个值。所以size为0,capacity为4。
还有一种思路,就是把指针赋为空,capacity赋为0.等到我们后面实际要用的时候,在根据情况来赋值。我就是这种写法
二,销毁
讲完了创建我们讲销毁,不为别的,就为简单。
销毁不就是把我们开辟的空间释放掉,指针赋值为空,size和capacity赋值为0.就行了。
三,主要功能
接下来就是主要功能,我们的功能就围绕增删查改,还有一个展示。这个5个来说。
1.增。
我们要增加联系人的时候,你会怎么想,是不是就打印提示信息给玩家,告诉他们怎么填,然后再scanf把信息收集起来,再放到SL类型创建的sl变量里面。
就是这样,但是我还是说心急吃不了热豆腐。我们存放数据是不是要空间啊,这个空间够不够啊,如果你是像我这样写的话,可能就直接发现了,因为我一开始就没有开辟空间啊。所以我们要先检查空间够不够。检查空间就判断一下capacity和size,如果size都等于capacity了,是不是空间就不够了啊,但是0 = 0 啊,这样就是还没开辟,就还有再来一个判断,size是不是为0,因此,和我不一样写法的兄弟有福了,计算机可以少判断一个,和我一样写法的兄弟,也不会亏待你们,对这下面看有没有什么问题。
到现在,我们的数据存放好了,但是存在变量里面还没有放到通讯录存放数据的地方去啊。
所以,我们来学习一种方法就是尾插,那怎么插呢,非常简单,就是把数据放到指针指向的空间,然后size再加加就行了。
严谨的我们不要忘记断言了噢。
虽然一个插入我分了3个函数但是,你们像写再一个函数还是可以的,但是像我一样的话要,注意函数内部创建的变量是临时变量,出了函数会销毁的,所以shuru函数里面一定要包含插入函数。才能把数据插入sl变量里面,你说放入sl变量为什么可以保存下来,sl变量不会销毁吗。哎……,传值调用和传址调用要分明白。还有就是大家看了我写的尾插,如果你们有兴趣的话,那你可以试一试头插
插入的大板块讲完了还有最后一个大板块就是删除,就还有一些细枝末节了
2.删除
我们要删除一个东西,要先干什么。想一想,上面我都没说要干什么,这次我还特别关心了一下你们,问了一句。
好,现在应该像到了吧,就是查找。我们要先删除一个数据,肯定要先看这个数据存不存在啊,他不存在你删个毛,是不是。那我们来讲查找。其实查找是很简单的,我们这个只有一个查找的方法,就是一个一个的比对,反正我的想不到(如果有大佬的话,评论区谈一谈吧)所以我们就直接上代码
这个就是假如找到了,就返回下标,如果没有找到的话就返回-1
我们后面就可以使用这个函数,我建议大家把这个函数像我这样写不要一个函数直接就把查找的全部完成了,因为我一开始就这样写的,后面发现在删除里面还有用到这样的函数,但是为了查找的全部实现,导致删除用不了,要从新写一遍。
删除也没什么好说的,就是如果删了一个不是最后面的数,你要把删后面的数据全部往前面移动。
轻舟已过万重山,后面的基本没上面说的。就是一个修改,我是这样的
你们怎么写看你们,也可以算为你们提供了思路
最后就是展示了一个for循环,大家都会就直接上代码了
但是你可以优化一下格式,我们后面见,拜拜