数据结构基础:2.顺序表。

news2024/11/16 9:17:23

顺序表的介绍和实现

  • 一.线性表
    • 1.基本概念:
  • 二.顺序表:
    • 1.基本概念:
    • 分类:1.静态顺序表:
    • 分类:2.动态顺序表:
    • 2.动态顺序表的功能接口的实现:
      • 0.顺序表打印:
      • 1.初始化和删除:
      • 2.尾插尾删:
      • 3.头插头删
      • 4.任意位置插入删除
      • 5.查找对应数据的下标。
      • 6.对于头插头删尾插尾删的优化:
      • 7.一个问题:
  • 三,整体代码和测试函数。
    • 一.声明:
    • 二,接口:
    • 三,主函数和测试函数。

一.线性表

1.基本概念:

1.线性表是N个相同相同特性的数据元素的有限的序列。线性表在实际中使用非常广泛使用的数据结构,常见的线性表有:顺序表,链表,栈,和队列,字符串。
2.线性表在逻辑上是一条直线,都是在物理结构上不一定是一个连续的,线性表在物理存储的时候,通常是以数组和链式结构的形式存储。

区分:
1.顺序表的物理结构是线性的。
2.链表的物理结构不是线性的。

二.顺序表:

1.基本概念:

顺序表是在物理地址上连续存储的的存储单元依次存储数据元素的线性结构,一般情况采用数组存储,在数组上完成对数据的增删查改。

分类:1.静态顺序表:

使用定长数组存储元素:
问题:我们这个数组的长度应该给多少合适?给多了使用不完浪费空间,给少了不够用。可以看出来这个方法不是一个好的顺序表,应该使用动态开辟的空间去作为我们顺序表存储空间的基础:

请添加图片描述

分类:2.动态顺序表:

使用动态开辟的数组存储元素:
请添加图片描述
请添加图片描述

2.动态顺序表的功能接口的实现:

函数统一的实参是结构体变量的地址,传地址调用才能改变顺序表。

0.顺序表打印:

//打印数据
void seqListPrint(SL* ps) 
{
	int n = ps->sz;
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

1.初始化和删除:

(注意)
malloc开辟初始空间大小,有效数据和容量的初始化。
free空间,指针置空,有效数据和容量变成空。

//初始化
void seqListInit(SL* ps)
{
	//动态开辟所以开始就开辟2个空间
	SL* pa = (SL*)malloc(sizeof(SL) * 4);
	if (pa == NULL)
	{
		perror("malloc fial");
		exit(-1);
	}
	ps->a = pa;
	ps->sz = 0;
	ps->capacity = 4;
}

//删除
void seqListDestort(SL* ps)
{
	free(ps->a);
	ps->capacity = 0;
	ps->sz = 0;
}

2.尾插尾删:

尾插:
1.容量足够:(加入之后有效数据个数++)
请添加图片描述

2.容量不够是需要增容的:
判断数据个数和当前的容量是否相同,相同需要增容,因为增容在插入的过程中是需要使用的所以我们封装一个函数用来增容:每次增加多少容量?建议每次增加容量的两倍这样可以避免空间的使用多次去扩容。

//增容函数
void seqListAdd(SL* ps)
{
	SL* pa = (SL*)realloc(ps->a, ps->capacity * 2 * sizeof(SL));
	if (pa == NULL)
	{
		perror("realloc file");
		exit(-1);
	}
	ps->a = pa;
	ps->capacity = ps->capacity * 2;
}
//尾插
void seqListPushBack(SL* ps, SLDataType x)
{
	if (ps->sz == ps->capacity)
	{
		//增容函数
		seqListAdd(ps);
	}
	//尾插
	ps->a[ps->sz] = x;
	ps->sz = ps->sz + 1;
}

尾删:
1.注意删除的一个问题没有了就不可以删除了。
2.断言函数:assert(ps->capacity>0)
3.关于capacity一但发生了错误就会结束程序,返回错误的行数。
4.比如删除到-1这个时候就直接结束程序:并返回错误的行数。

//尾删
void seqListPopBack(SL* ps)
{
	assert(ps->sz > 0);
	ps->sz = ps->sz - 1;
}

3.头插头删

头插
1.头插每一次的位置是固定的。
2,这个位置在插入的之前要空出来,整个数据需要进行移动。
3.最后一个赋值到下一个,以此类推直到把第一个赋值到第二个结束。
4.在插入的过程中需要进行一个数据的移动说明这个效率是非常底。每一次插入之前需要进行时复位N的移动。

//头插
void seqListPushFront(SL* ps, SLDataType x)
{
	//头插的时间复杂度是非常高的,进行一个数据移动。
	if (ps->sz == ps->capacity)
	{
		//增容
		seqListAdd(ps);
	}

	//1.移动
	int n = ps->sz;
	for (int i = n; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->sz == ps->sz++;
}

头删:
1.删除位置固定第一个。
2.第二个赋值到第一个,一直到最后一个赋值到倒数第二个位置。
3…有效数据个数–。
4.使用断言判断是否已经没有内容可以删除了。

//头删
void seqListPopFront(SL* ps)
{
	//头删的时间复杂度是非常高的,进行一个数据移动。
	assert(ps->sz > 0);
	ps->sz = ps->sz - 1;
	int n = ps->sz;
	for (int i = 0; i < n-1; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
}

4.任意位置插入删除

任意位置pos是通过函数的一个参数确定任意位置的下标
1.从末尾开始最后一个赋值到下一个,直到pos位置的置赋值到下一个的时候。
2.这个数据就可以放到pos位置。
3.增容函数
4.有效数据++

// 顺序表在pos位置插入x
// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x)
{
	if (ps->sz == ps->capacity)
	{
		seqListAdd(ps);
	}

	//在对应位置插入数值。
	int n = ps->sz;
	for (int i = n; i >pos ; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}

	ps->a[pos] = x![请添加图片描述](https://img-blog.csdnimg.cn/837991a19f794402be4534f9b324441a.png)
;
	ps->sz++;
}

1.把这个位置的置覆盖,pos+1覆盖到pos最后一个覆盖到倒数第二个上就结束了。
2.有效数据个数–。

// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos)
{
	assert(ps->sz > 0);
	int n = ps->sz;
	for (int i = pos; i < n-1; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
	ps->sz--;
}

5.查找对应数据的下标。

1.我们想要删除一个确定的数据可以通过查找函数返回对应数据的下标。
2.然后再使用任意位置插入删除的函数去删除这个数据。
3.遍历动态开辟数组去查找数据返回下标。找不到就返回-1数。
4.使用之前判断一下如果返回值为-1说明数据不存在。

// 顺序表查找
int SeqListFind(SL* ps, SLDataType x)
{
	//遍历查找
	int n = ps->sz;
	for (int i = 0; i < n; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

6.对于头插头删尾插尾删的优化:

对于他们来说就是插入删除的位置固定,我们使用任意位置的插入删除函数去复用实现头插头删尾插尾删功能。

请添加图片描述

7.一个问题:

函数使用之前断言一下结构体的指针是否为空指针。

三,整体代码和测试函数。

一.声明:

#pragma once

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<assert.h>

typedef int SLDataType; 
//定义的数组,当前数组中元素个数,容量。

typedef struct seqlist {
	SLDataType* a;//指向动态开辟的数组
	int sz;//数组的有效数据个数
	int capacity;//容量空间的大小
}SL;


//初始化
void seqListInit(SL* ps);

//删除
void seqListDestort(SL* ps);

//尾插
void seqListPushBack(SL*ps, SLDataType x);

//尾删
void seqListPopBack(SL* ps);

//头插
void seqListPushFront(SL* ps, SLDataType x);

//头删
void seqListPopFront(SL* ps);

//打印数据
void seqListPrint(SL* ps);

// 顺序表查找
int SeqListFind(SL* ps, SLDataType x);

// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x);

// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);

二,接口:

#include"seqlist.h"

// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x);

// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos);


//初始化
void seqListInit(SL* ps)
{
	//动态开辟所以开始就开辟2个空间
	SL* pa = (SL*)malloc(sizeof(SL) * 4);
	if (pa == NULL)
	{
		perror("malloc fial");
		exit(-1);
	}
	ps->a = pa;
	ps->sz = 0;
	ps->capacity = 4;
}

//删除
void seqListDestort(SL* ps)
{
	free(ps->a);
	ps->capacity = 0;
	ps->sz = 0;
}

//打印数据
void seqListPrint(SL* ps)
{
	int n = ps->sz;
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

//增容函数
void seqListAdd(SL* ps)
{
	SL* pa = (SL*)realloc(ps->a, ps->capacity * 2 * sizeof(SL));
	if (pa == NULL)
	{
		perror("realloc file");
		exit(-1);
	}
	ps->a = pa;
	ps->capacity = ps->capacity * 2;
}

//尾插
void seqListPushBack(SL* ps, SLDataType x)
{
	if (ps->sz == ps->capacity)
	{
		//增容函数
		seqListAdd(ps);
	}
	//尾插
	ps->a[ps->sz] = x;
	ps->sz = ps->sz + 1;
}

//尾删
void seqListPopBack(SL* ps)
{
	assert(ps->sz > 0);
	ps->sz = ps->sz - 1;
}

//头插
void seqListPushFront(SL* ps, SLDataType x)
{
	SeqListInsert(ps, 0, x);
	//头插的时间复杂度是非常高的,进行一个数据移动。
	//if (ps->sz == ps->capacity)
	//{
	//	//增容
	//	seqListAdd(ps);
	//}

	1.移动
	//int n = ps->sz;
	//for (int i = n; i > 0; i--)
	//{
	//	ps->a[i] = ps->a[i - 1];
	//}
	//ps->a[0] = x;
	//ps->sz == ps->sz++;
}

//头删
void seqListPopFront(SL* ps)
{
	SeqListErase(ps, 0);
	//头删的时间复杂度是非常高的,进行一个数据移动。
	/*assert(ps->sz > 0);
	ps->sz = ps->sz - 1;
	int n = ps->sz;
	for (int i = 0; i < n-1; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
	*/
}


// 顺序表查找
int SeqListFind(SL* ps, SLDataType x)
{
	//遍历查找
	int n = ps->sz;
	for (int i = 0; i < n; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

// 顺序表在pos位置插入x
void SeqListInsert(SL* ps, int pos, SLDataType x)
{
	if (ps->sz == ps->capacity)
	{
		seqListAdd(ps);
	}

	//在对应位置插入数值。
	int n = ps->sz;
	for (int i = n; i >pos ; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}

	ps->a[pos] = x;
	ps->sz++;
}

// 顺序表删除pos位置的值
void SeqListErase(SL* ps, int pos)
{
	assert(ps->sz > 0);
	int n = ps->sz;
	for (int i = pos; i < n-1; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
	ps->sz--;
}

三,主函数和测试函数。

void test3(SL *ps)
{
	seqListPushBack(ps, 1);
	seqListPushBack(ps, 2);
	seqListPushBack(ps, 3);
	seqListPushBack(ps, 4);
	seqListPushBack(ps, 5);
	seqListPushBack(ps, 6);

	seqListPrint(ps);

	seqListPushFront(ps, 7);
	seqListPushFront(ps, 8);
	seqListPushFront(ps, 9);
	seqListPushFront(ps, 10);

	seqListPrint(ps);

	int x=SeqListFind(ps, 11);
	if (x == -1)
	{
		printf("没有\n");
	}

	SeqListInsert(ps, 5, 20);
	SeqListInsert(ps, 6, 30);
	SeqListInsert(ps, 7, 50);

	seqListPrint(ps);

	SeqListErase(ps, 5);
	//seqListPrint(ps);
	SeqListErase(ps, 5);
	//seqListPrint(ps);
	SeqListErase(ps, 5);

	seqListPrint(ps);
}

int main()
{
	SL a;
	//初始化
	seqListInit(&a);

	//测试1
	//test1(&a);

	//测试2
	//test2(&a);

	//测试3
	test3(&a);


	//释放空间
	seqListDestort(&a);
	return 0;
}

今天的分享就到这里了谢谢大家的阅读,我也会更加努力给大家带来更加优质的文章的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/798148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

功率放大器在电光调制中的应用有哪些

电光调制是一种利用光电效应将电信号转化为光信号的技术。在实现电光调制的过程中&#xff0c;功率放大器作为一个重要的组件&#xff0c;具有对输入电信号进行放大和控制的功能。本文将介绍功率放大器的基本原理、特点以及在电光调制中的应用。 基本原理 功率放大器是一种能够…

新建Git仓库,将本地文件上传至仓库

1、新建仓库&#xff0c;勾选初始化仓库 2、复制仓库链接 3、打开本地文件目录 右键选择 Git Bash Here 打开命令窗口 4、依次按照下面的步骤&#xff08;*如果报错&#xff0c;看原目录下是否存在 .git 需要删除&#xff09; // 生成git文件 git init // 把文件加入暂存区 g…

DeepSpeed-MoE:训练更大及更复杂的混合专家网络

这是微软发布在2022 ICML的论文&#xff0c;MoE可以降低训练成本&#xff0c;但是快速的MoE模型推理仍然是一个未解决的问题。所以论文提出了一个端到端的MoE训练和推理解决方案DeepSpeed-MoE&#xff1a;它包括新颖的MoE架构设计和模型压缩技术&#xff0c;可将MoE模型大小减少…

Java基础篇

前言&#xff1a;此篇博客笔者参考了JavaGuide、三分恶等博主的八股文&#xff0c;结合Chat老师和自己的理解&#xff0c;整理了一篇关于Java基础的八股文。全篇图文并茂&#xff0c;每个知识点都有细致描述&#xff0c;详略得当&#xff0c;理解通透。希望对各位读者有所帮助&…

Python(四十二)流程控制语句——continue

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

reids集群删除某个集群节点

由于服务期调整&#xff0c;已经配好的集群&#xff0c;要删除几个节点&#xff0c;利用命令redis-cli --cluster del-node ip:prot 结果删除失败了&#xff0c;报错&#xff1a; ERR Unknown subcommand or wrong number of arguments for del-node。help查了下&#xff0c;没…

【数据结构】实验二:顺序表

实验二 顺序表 一、实验目的与要求 1&#xff09;熟悉顺序表的类型定义&#xff1b; 2&#xff09;熟悉顺序表的基本操作&#xff1b; 3&#xff09;灵活应用顺序表解决具体应用问题。 二、实验内容 1&#xff09;在一个整数序列a1,a2,…,an中&#xff0c;若存在一个数&…

调用post请求方式的feign接口怎么传递多个参数,包含对象和字符串

今天尝试把自己原来的项目上的权限管理相关的类抽离开来&#xff0c;并建立一个统一的权限管理平台&#xff0c;然后项目中要用到的权限相关资源通过feigin请求权限平台的对应接口获取。 现在有一个需求&#xff0c;页面上有一个一键获取资源权限的按钮&#xff0c;点击一下&a…

python_PyQt5开发验证K线视觉想法工具V1.0

目录 写在前面&#xff1a; 使用过程&#xff1a; 代码&#xff1a; 导入的包、字符型横坐标、K线控件 K线图控件 放置标记数据表格控件 输入并设置标记数据控件 主界面 运行代码 写在前面&#xff1a; 开发这个工具的初衷&#xff0c;是基于在分析股票实践中想批量计算…

Django实现音乐网站 ⑴

使用Python Django框架制作一个音乐网站。 目录 网站功能模块 安装django 创建项目 创建应用 注册应用 配置数据库 设置数据库配置 设置pymysql库引用 创建数据库 创建数据表 生成表迁移文件 执行表迁移 后台管理 创建管理员账户 启动服务器 登录网站 配置时区…

神码ai火车头伪原创设置【php源码】

大家好&#xff0c;给大家分享一下python考什么内容&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 火车头采集ai伪原创插件截图&#xff1a; 1、Python 计算机二级都考什么 Python要到什么程度 考试内容 一、Python语言的基本语法元素…

高算力AI模组前沿应用:基于ARM架构的SoC阵列式服务器

本期我们带来高算力AI模组前沿应用&#xff0c;基于ARM架构的SoC阵列式服务器相关内容。澎湃算力、创新架构、异构计算&#xff0c;有望成为未来信息化社会的智能算力底座。 ▌性能优势AI驱动&#xff0c;ARM架构服务器加速渗透 一直以来&#xff0c;基于ARM架构的各类处理器…

Tooltip文字提示(antd-design组件库)简单使用

1.Tooltip文字提示 简单的文字提示气泡框。 2.何时使用 鼠标移入则显示提示&#xff0c;移出消失&#xff0c;气泡浮层不承载复杂文本和操作。 可用来代替系统默认的 title 提示&#xff0c;提供一个 按钮/文字/操作 的文案解释。 组件代码来自&#xff1a; 文字提示 Tooltip -…

读写分离案例、Mysql主从复制 步骤

在开发大型应用程序时&#xff0c;数据库的性能通常是一个关键问题。读写分离是一种常见的数据库优化技术&#xff0c;可以显著提升数据库的读取操作性能。本文将介绍MySQL主从复制和一个读写分离案例。 1、MySQL主从复制 主从复制是MySQL数据库提供的一种数据复制机制&#…

免费商城搭建、免费小程序商城搭建、之java商城 电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

【黑马头条之内容安全第三方接口】

本笔记内容为黑马头条项目的文本-图片内容审核接口部分 目录 一、概述 二、准备工作 三、文本内容审核接口 四、图片审核接口 五、项目集成 一、概述 内容安全是识别服务&#xff0c;支持对图片、视频、文本、语音等对象进行多样化场景检测&#xff0c;有效降低内容违规风…

vue+ivew model框 select校验遇到的问题

iview model 点击关闭&#xff0c;校验没有通过也会关闭 解决办法&#xff1a; 第一步&#xff1a;自定义页脚内容 <div slot"footer"><Button type"primary" click"confirmCarryOver()">确认</Button><Button click&qu…

python绘制3D条形图

文章目录 数据导入三维条形图bar3d 数据导入 尽管在matplotlib支持在一个坐标系中绘制多组条形图&#xff0c;效果如下 其中&#xff0c;蓝色表示中国&#xff0c;橘色表示美国&#xff0c;绿色表示欧盟。从这个图就可以非常直观地看出&#xff0c;三者自2018到2022年的GDP变化…

智能制造:开启工业新纪元

随着科技的不断发展和人工智能的日益成熟&#xff0c;智能制造正成为当今工业界的热门话题。智能制造是一种以先进技术为支撑&#xff0c;通过数字化、网络化、智能化手段来提升生产效率、优化生产流程的现代化制造模式。 在智能制造中&#xff0c;物联网、大数据、云计算、人工…

OR-Tools工具安装(Python-Vs code)-自用

安装&#xff08;已安装python以及Vs code&#xff09; pip安装 python -m pip install --user ortools安装完成示意如下&#xff1a; 验证安装 python -c "import ortools; print(ortools.__version__)"输出结果为版本号