空间复杂度&动态顺序表

目录

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(顺序表头文件,可以自己取名,这边方便看就取直译英文)

cs 复制代码
#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(顺序表源文件)

cs 复制代码
#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(测试源文件)

cs 复制代码
#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>>结语

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

相关推荐
No0d1es19 分钟前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
大阳1232 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
weixin_307779134 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
学行库小秘4 小时前
ANN神经网络回归预测模型
人工智能·python·深度学习·神经网络·算法·机器学习·回归
没落之殇4 小时前
基于C语言实现的HRV分析方法 —— 与Kubios和MATLAB对比
算法
FPGA4 小时前
探讨4B/5B编码、8B/10B编码区别以及FPGA实现
数据结构
秋难降4 小时前
线段树的深度解析(最长递增子序列类解题步骤)
数据结构·python·算法
楚韵天工5 小时前
基于GIS的无人机模拟飞行控制系统设计与实现
深度学习·算法·深度优先·无人机·广度优先·迭代加深·图搜索算法
你也向往长安城吗6 小时前
推荐一个三维导航库:three-pathfinding-3d
javascript·算法
百度智能云6 小时前
VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
算法