博主关于C语言的博客就先告一段落了,以后更难的数据结构在等着我们!!!!!!
在讲顺序表之前,我们要先引入一个概念,那就是线性表
1.线性表
线性表,是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表(我们本片博客主讲的内容)、单链表(博主正在学的),栈,队列,字符串。
线性表在逻辑上是线性结构,也就是说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常是数组和链式结构的形式存储。
通俗的说,如果存储的数据随着下标的增大,地址也增大的话,那么就是属于物理结构上的线性,例如我们所学的数组,可以通过下标来访问数组中的各个元素(这个成立的前提条件就是这个数组中的数据的物理结构是线性的)
而什么是逻辑结构线性呢?这里博主画个图帮助大家理解
例如我们家里的东西丢得杂乱无章,这时我们可能会用一个东西把它们规整起来,例如

我们使用了一个柜子来存放这些毫无关联的杂物,使得它们在柜子的前提下看起来有序了起来,我们这种人为想象出来的,对无关联事物用一个类似框架绑定起来,看上去显得有逻辑,这就是逻辑结构,所以逻辑结构一定是线性的。
顺序表
在讲完了线性表之后,顺序表的结构我们就可以有清晰的了解了
顺序表:
逻辑结构:线性的
物理结构:线性的(也就是说顺序表中的数据在地址上一定是连续的,所以我们可以用下标来访问顺序表的数据)
顺序表和数组的关系是什么?这个问题可有趣多了!!!我会举例子来帮助大家更好的理解这个问题
(1)我们平常想吃炒西兰花,去那种普通的餐馆,炒西兰花就叫炒西兰花。而要是我们去高档餐厅吃西兰花呢?你翻开菜单,你就会发现炒西兰花变成了另外一种高大上的名字———绿叶仙踪。这个绿野仙踪就是在西兰花的基础上,给他增添一点料汁,小饰品,以及各种各样的摆盘,当然,价格也就贵了很多
(2)再比如,我们想吃玉米羹,普通的餐厅肯定就叫玉米羹,但在高档的米其林餐厅呢?可能就叫做宫廷玉液羹,也是在玉米羹的基础上,加上点料汁,摆盘啥的
所以,数组和顺序表也是这样的一种关系,只不过我们无法对数组进行元素删除,元素插入等等操作,而顺序表就是在数组的基础上,增加了查找数据,删除数据等操作
以上是重点,请大家务必理解清楚。!!!!!!!!!!!!!!!
顺序表的三元素
1.指向内存空间的arr
2.顺序表中的有效数据个数size
3.顺序表的容量capacity

初始化顺序表
都说顺序表有三元素,那么前面C语言我们哪里学到了这样的一种变量来整合不同类型的变量呢?没错,就是结构体变量,为了防止有人忘记了这个知识点,我们来复习一下结构体的相关知识吧
结构体需包含struct关键字,比如我们想定义一个关于学生的结构体变量,这里包含了学生的名字,学生的年龄,学生的成绩等
struct Stu
{
char name[];//存放学生名字的数组
int age;//存放学生的年龄
float score;//存放学生的成绩
};
int main()
{
struct Stu st;//创建st变量
st.name = "lisi";//对st这个结构体变量中的name进行初始化
st.age = 16;//对st这个结构体变量中的age进行初始化,为16
st.score = 98.5;//对这个结构体表变量中的score进行初始化,为98.5
return 0;
}
以上就是博主对结构体进行的一个简单复习
接下来,我将通过画图,为大家直观地展示结构体各个成员的作用

顺序表的初始化
我们先对顺序表进行初始化,方便我们后面对其的操作,初始化指针为NULL,size有效数据为0,capacity容量也为0。即:
typedef int SLdatatype
typedef struct Seplist
{
SLdatatype * arr;
int size;
int capacity;
}SL;
void SLinit(SL * ps)
{
ps->arr = NULL;
ps->size = 0;
ps->capacity = 0;
}
void test01()
{
SL sl;
SLinit(&sl);
}
int main()
{
test01();
return 0;
}
上面的代码得有一定的功底,才能看得懂,我先对几行有意义的代码进行讲解,其他有不懂的可以私信博主
1.typedef int SLdatatype
这行代码的意思就是将int转化为SLdatatype,也就是说打完这段代码后,SLdatatype a,就相当于int a。
typedef关键字有重命名的作用,就是将一些复杂的关键字转化为我们自定义的,易操作打出来的字母。
我们知道,数组可以存放多种数据类型,那么,顺序表也一样,要是我们只是单纯的在结构体的定义上写 int * arr,那么后面的代码都得是int型,要是我们想使用顺序表存放float变量,就得一行一行地改类型,所以,我们干脆typedef int SLdatatype,以后想改类型直接把int改成我们想要的类型即可。就不用大费周章地一行一行的改代码
2.typedef struct Seplist
{
…;
}SL;
一般来说,结构体的名称都是很长的,我们呢想对结构体进行typedef操作(即对结构体进行改名操作)该怎么办呢,其实,先在struct…前面加上typedef即可,即typedef struct…,再在下面的大括号后加上你想重新定义的名字即上方的SL。
3.int size
int capacity
这里我猜大家的疑问应该是为什么不跟上面arr一样,使用SLdatatype指针。我再说一遍,size和capacity是有效数据个数,是真真正正的整型类型,是多少个有效个数,有多大的容量!!!大家不可以搞混了
增容
大家有没有想过,我们一开始初始化的顺序表size和capacity全都是0,那这样难道不是近似于一个空表吗?所以在对顺序表进行任何操作的时候,我们都应该增容(空间有限另当别论),那么,该如何进行增容呢?
这里的操作涉及到动态内存管理函数,还没学习的可以看我的博客https://editor.youkuaiyun.com/md/?articleId=146161440
————————我们直接把代码给大家般过来,再一一进行讲解

如图,就是增容操作的具体代码
增容,无非就是增加capacity,我们的目的就是把capacity增加到4(这个数字随大家而定),可别忘了,capacity只是一个表示容量的数字,用来客观表示的而已。真正能做到扩展容量的还得是使用arr指针,再配合上realloc函数进行扩展
咱们先来看第一段代码。if(ps->size == ps->capacity)
这里其实就是代码容量满了的意思,就是顺序表存储的是数据个数已经达到了capacity的极限,例如
上面我们提到了,arr指向这块内存空间,所以我们通过realloc函数来对arr指向的空间进行扩容即可
realloc(void * ,size_t size):第一个参数指向要扩容的空间的地址,第二个是要将此指针所指向的空间扩展成多大字节的空间,用capacity*sizeof(SLdatatype)就是扩展后的内存大小。
接下来我们来看一行神之一手的代码!!!!
int newcapacity = capacity ==0?4:2*capacity;
这里先说明一下,因为增加capacity不好增加,所以先用newcapacity来代替capacity增加后的值,再通过复制把newcapacity的值传给capacity
capacity ==0?4:2*capacity
这里使用到了三目操作符。A?B:C。即A如果为真,那这个式子整体取B,若A为假,那这个式子整体就等于C
这里的意思就是在说明
->(1.)若capacity为0,那么就让它等于4,然后赋值给newcapacity(后续再通过赋值,将newcapacity的值赋给capacity,也就是说,后续capacity将会得到4)
->(2.)若capacity不等于0,就比如容量capacity等于4,然后已经被用满了,现在要将capacity扩大两倍,就走的上面C的值,也就是2*capacity,最后会通过newcapacity赋值给capacity,也就是8.
现在capacity增加完毕,接下来需要怎么操作呢?
就是使用realloc给arr指向的内容增容
SLdatatype * tmp = (SLdatatype*)realloc(ps->arr,sizeof(SLdatatype)*newcapacity)
(1)这里使用tmp接收的原因是,realloc开辟空间可能会失败,失败了,那个指向内存的指针会变成NULL,会导致我们先前再顺序表里面存放的数据将会丢失,所以用中介tmp来接收,如果其为NULL,那就退出程序,如果它不为NULL,那就将其赋值给ps->arr。是这么个逻辑。
(2)这里的sizeof(SLdatatype)newcapacity,就是代表我们进行增容操作开辟内存后的字节数,newcapacity是代表可以存放多少个数据,sizeof(SLdatatype)就表示一个数据的字节数,它们相乘就表示内存空间的总字节数。eg.这里SLdatatype我们取int,那么sizeof(int) newcapacity=4*8就等于32(字节);
(3)最后,再将tmp赋给ps->arr指针,newcapacity赋给capacity。
自此,增容部分我们就讲完了。
顺序表是一个比较复杂的数据结构,所以我分成了三集,这里是第一集,往后我会写出更多的博客,帮助大家更好的理解顺序表

921

被折叠的 条评论
为什么被折叠?



