空间复杂度&动态顺序表

目录

1>>闲话

2>>空间复杂度 

3>>顺序表!!(有点难度)

3.1>>静态顺序表

3.2>>动态顺序表

3.2.1>>初始化动态顺序表

3.2.2>>实现尾插

4>>结语


1>>闲话

        感谢大家对小编文章的喜欢,小编会继续加油的,今天来分享空间复杂度和线性表里的顺序表部分内容,今天内容难度有点高,希望大家刚接触的坚持一下!

2>>空间复杂度 

        空间复杂度是对一个算法在运行过程中需要的额外临时开辟的空间。空间复杂度和时间复杂度一样,都是使用大O渐进表示法,

(不知道的参考上一篇文献:链接博主回归!数据结构篇启动-CSDN博客)

因为主要看重时间复杂度,所以空间就不过多介绍了,这边附上一题练习题,一起来看看这题的空间复杂度是多少吧:

这里调用了n次,创建了n个函数栈帧空间,所以空间复杂度为O(N)。

3>>顺序表!!(有点难度)

        刚学大家肯定和我有一样的疑问?这是个啥?其实顺序表是线性表的一种线性表分为顺序表、链表、栈、队列、字符串等等。线性表表示逻辑上是线性结构,物理结构不一定线性,我们通常学的数组就是物理结构连续的,也就是线性的,逻辑结构线性就表示我们想象的它是线性的一条线

接下来让我们来学习顺序表:顺序表是物理地址也是连续的一段线性结构,一般用数组存储表示。那大家又有疑问哩,顺序表和数组有啥区别?顺序表是数组的升级改造版本,实现了增删改查的操作

顺序表又分为静态顺序表和动态顺序表。

3.1>>静态顺序表

        静态顺序表不怎么常用,因为不实用,内存固定,要么设置太大造成空间浪费,要么设置太小造成空间不够,所以我们直接来学习动态。

3.2>>动态顺序表

3.2.1>>初始化动态顺序表

        实现动态顺序表需要三个文件:顺序表头文件、顺序表源文件、测试文件

        这边先附上代码(这里实现了动态顺序表的尾插功能),大家先看(不懂没事,后面一句句介绍):

seqlist.h(顺序表头文件,可以自己取名,这边方便看就取直译英文)

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int datetype;//不知道具体类型,可以一下子改

typedef struct seqlist {
	datetype* arr;//(顺序表数组实现增、删、改、查)动态顺序表
	int size;//有效数据
	int capacity;//容量(包含有效和浪费的数据)
}SL;//将struct seqlist 重命名为typedef

void SLset(SL* ps);//初始化声明

void SLpushback(SL* ps, datetype x);//尾插

seqlist.c(顺序表源文件)


#include"seqlist.h"

void SLset(SL* ps) {
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void SLpushback(SL* ps, datetype x) {//x是插入数据
	//情况2:空间不够进行扩容
	assert(ps != NULL);
	if (ps->capacity == ps->size) {
		//空间不足,扩容
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		datetype* tmp = (datetype*)realloc(ps->arr, newcapacity * sizeof(datetype));
		if (tmp == NULL) {
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

	ps->arr[ps->size++] = x;//情况1:空间够直接加
}

test.c(测试源文件)

#include"seqlist.h"

void SLtest() 
{
	SL sl;
	SLset(&sl);//初始化
	SLpushback(&sl, 1);
}
int main() 
{

	SLtest();
	return 0;
}

这边看不懂正常,难度上来了,前期看不懂是小问题滴,现在容许我一句句介绍叭。

首先:要实现动态顺序表,最基础的部分就是结构体的创建

typedef是重命名的意思,第一句表示吧int重命名为datetype,因为如果是char型的话只需要更改这里就好。其他的我已经在注释解释啦~大家康康。还有第二句的typedef是将struct seqlist重命名为SL

其次,创建完顺序表那么就要初始化里面的值,在顺序表头文件进行声明

这里使用结构体指针接收,这样在函数内才能修改到顺序表SL里面的每一项值。接着在顺序表源文件里包含头文件:

创建一个无返回值函数 SLset,通过ps指针接受结构体指针,这样才能修改里面的值,然后将arr设置为空,这样自行拓展方便,接着将有效数和容量设置为0.

接着在测试文件进行操作:

写一个测试函数SLtest,当然在main里直接写也可以(这边考虑文件较大时不好看所以拿一个函数来写里面),创建结构体变量sl,将sl取地址传到初始化函数进行初始化!一定注意传的是地址!

好了至此初始化顺序表结束!

3.2.2>>实现尾插

        尾插顾名思义就是在顺序表尾部进行插入数值,那么就要考虑到两种情况,空间够与不够:

现在头文件声明尾插函数SLpushback,需要有一个结构体指针接收,还要一个传进行来要插入尾部的值。

接着在顺序表源文件实现尾插代码:

情况1:空间够,数组【有效数值】就是需要插入的尾部空间,如:

arr={1,2,3,空},空表示多余空间,那么空下标是3,有效数值有3个,所以数组【有效数值】就是需要插入的尾部空间。

情况2:空间不够,那么就要另外开辟空间,我们一般将原有空间乘2,那什么时候进行扩容呢?再举例子说明,arr={1,2,3},此时有效三个,容量也是3个,那么size等于capacity时进行扩容!

也就是这行代码,还需要判断原本容量是否为0:

这里用三目操作符,如果为0那么就为4,否则就扩大两倍存放到新容量(newcapacity)

接下来就要使用realloc对arr进行扩容,要先判断内存是否有空间,没空间返回值是NULL,所以这里为了防止arr得到一个空值,那么就要不嫌麻烦再创建一个同类型指针接受地址。

这里还需要乘上sizeof(datetype),因为realloc扩容的是字节数,所以要乘上这个类型一个占多少字节

接着为空打印错误信息:

如果不为空那么往下走,让原来的arr接受新的tmp大小,然后容量变为新容量。

这里传一个值

就可以实现最终代码啦,大家可以自己写写调试看看

那么至此!尾插结束!

4>>结语

        总结:这篇讲述了空间复杂度和线性表里的顺序表,主要讲述了动态顺序表的尾插概念!呼~结束了,对于刚接触的我觉得还是有点难度的,不过通过这篇博客加深了印象,不至于一头雾水,也希望这篇博客能帮助到同样一头雾水的你们,感谢观看,期待与你,下篇相见!谢谢大家!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫の大一

谢谢大佬,我会三连你的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值