【数据结构与算法】线性表 - 顺序表

news2025/1/19 17:10:06

目录

  • 1. 线性表
  • 2.顺序表
  • 3.顺序表的优缺点
  • 4.实现(C语言)
    • 4.1 头文件 seqList.h
    • 4.2 实现 seqList.c

1. 线性表

  线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

  线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
在这里插入图片描述

2.顺序表

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

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。
  2. 动态顺序表:使用动态开辟的数组存储。

  静态顺序表只适用于确定知道需要存多少数据的场景,静态顺序表的定长数组,长度N定大了,空间开多了浪费,开少了不够用。所以基本都是使用动态顺序表,根据需要动态的分配空间大小。

3.顺序表的优缺点

缺点:增删改速度慢。

  1. 中间 / 头部的插入删除,时间复杂度为O(N)。
  2. 增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。
  3. 增容一般是呈1.5或2倍的增长,势必会有一定的空间浪费。

优点:有数组索引,查询速度快。

4.实现(C语言)

4.1 头文件 seqList.h

#pragma once

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

// 初始大小
#define STD_SIZE 4

// 顺序表数据类型
typedef int seqListDataType;

// 顺序表
typedef struct SeqList 
{
	seqListDataType* list;
	int size; // 有效数据个数
	int cap; // 顺序表容量
} SeqList;

// 初始化,销毁
void init(SeqList* psl);
void destroy(SeqList* psl);

// 扩容
void checkResize(SeqList* psl);

// 头插头删,尾插尾删
void addFront(SeqList* psl, seqListDataType ele);
void removeFront(SeqList* psl);
void addBack(SeqList* psl, seqListDataType ele);
void removeBack(SeqList* psl);

// 指定位置[0-size+1)插入,[0~size)删除
void insert(SeqList* psl, int pos, seqListDataType ele);
void erase(SeqList* psl, int pos);

4.2 实现 seqList.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "seqlist.h"

// 初始化
void init(SeqList* psl)
{
	assert(psl);
	psl->list = NULL;
	psl->size = 0;
	psl->cap = 0;
}

// 销毁
void destroy(SeqList* psl)
{
	assert(psl && psl->list);
	free(psl->list);
	psl->list = NULL;
	psl->size = 0;
	psl->cap = 0;
}

// 检查容量并扩容
static void checkResize(SeqList* psl)
{
	if (psl->size == psl->cap) 
	{
		int newCap = psl->size == 0 ? STD_SIZE : psl->cap * 2;
		seqListDataType* tmpList = realloc(psl->list, newCap * sizeof(seqListDataType));
		if (tmpList != NULL)
		{
			psl->list = tmpList;
			psl->cap = newCap;
			// 只将扩容的内存置0
			memset((psl->list) + psl->size, 0, psl->size * sizeof(seqListDataType));
		}
		else
		{
			perror("checkCap(SqList* psl) realloc error");
		}
	}
} 

// 头插
void addFront(SeqList* psl, seqListDataType data)
{
	assert(psl);
	checkResize(psl);
	// 所有元素往后挪1位
	for (int i = psl->size - 1; i >= 0; i--)
	{
		psl->list[i + 1] = psl->list[i];
	}
	psl->list[0] = data;
	psl->size++;
}

// 头删
void removeFront(SeqList* psl)
{
	assert(psl && psl->size > 0);
	// 第2个元素开始,所有元素往前挪1位
	for (int i = 1; i < psl->size; i++)
	{
		psl->list[i - 1] = psl->list[i];
	}
	psl->list[psl->size - 1] = 0;
	psl->size--;
}

// 尾插
void addBack(SeqList* psl, seqListDataType data)
{
	assert(psl);
	checkResize(psl);
	psl->list[psl->size] = data;
	psl->size++;
}

// 尾删
void removeBack(SeqList* psl)
{
	assert(psl && psl->size > 0);
	psl->list[psl->size - 1] = 0;
	psl->size--;
}

// 指定位置[0-size+1)插入
void insert(SeqList* psl, int pos, seqListDataType ele)
{	
	assert(psl);
	checkResize(psl);
	assert(pos >= 0 && pos < psl->size + 1);
	// 从插入位置开始,所有元素向后挪动1位
	for (int i = psl->size - 1; i >= pos; i--)
	{
		psl->list[i + 1] = psl->list[i];
	}
	psl->list[pos] = ele;
	psl->size++;
}

// 指定位置[0~size)删除
void erase(SeqList* psl, int pos)
{
	assert(psl && pos >= 0 && pos < psl->size);
	// 从删除位置开始,所有元素往前移动1位
	for (int i = pos; i < psl->size; i++)
	{
		psl->list[i] = psl->list[i + 1];
	}
	psl->list[psl->size - 1] = 0;
	psl->size--;
}

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

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

相关文章

13.真刀实枪做项目---博客系统(页面设计)

文章目录 1.预期效果1.1博客列表页效果1.2博客详情页效果1.3博客登陆页效果1.4博客编辑页效果 2.实现博客列表页2.1实现导航栏2.2实现版心2.3实现个人信息2.4实现博客列表2.5博客列表页完整代码 3.实现博客正文页3.1引入导航栏3.2引入版心3.3引入个人信息3.4实现博客正文3.5博客…

什么是java反射机制?

类的正常加载 反射概述 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&#xff1b;这种动态获取的信息以及动态调用对象的方法的功能称为jav…

Filter和ThreadLocal结合存储用户id信息

ThreadLocal并不是一个Thread&#xff0c;而是Thread的局部变量。当使用ThreadLocal维护变量时&#xff0c;ThreadLocal为每个使用该变量的线程提供独立的变量副本&#xff0c;所以每一个线程都可以独立地改变自己的副本&#xff0c;而不会影响其它线程所对应的副本。ThreadLoc…

基于PI+重复控制的并网逆变系统谐波抑制策略模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; PI重复控制简介&#xff1a; 重复控制这一新型控制理论最早于出现日本学术界&#xff0c;其目的是为了用于解决质子加速器跟踪精度的问题。Yamamoto Y 等人提出了重复控制数学基础的内模原理&#xff0c;在控…

编写程序,要求输入x的值,输出y的值。分别用(1)不嵌套的if语句(2)嵌套的if语句(3)if-else语句(4)switch语句。

编写程序&#xff0c;要求输入x的值&#xff0c;输出y的值。分别用&#xff08;1&#xff09;不嵌套的if语句&#xff08;2&#xff09;嵌套的if语句&#xff08;3&#xff09;if-else语句&#xff08;4&#xff09;switch语句。 选择结构是编程语言中常用的一种控制结构&…

网工内推 | Linux运维,六险二金,最高30K,IE认证优先

01 上海域起 招聘岗位&#xff1a;Linux运维工程师 职责描述&#xff1a; 1.负责游戏产品运维相关的工作&#xff0c;流程文档、技术文档、功能脚本的编写整理 2.负责分析并排除系统、数据库、网络、应用等游戏产品运维中出现的故障及错误 3.负责对游戏产品项目进行线上部署、…

电磁场与电磁波part3--静态电磁场及其边值问题的解

1、当场源&#xff08;电荷、电流&#xff09;不随时间变化时&#xff0c;所产生的电场、磁场也不随时间变化&#xff0c;称为静态电磁场。静止电荷产生的静电场、在导电媒质中恒定运动电荷形成的恒定电场以及恒定电流产生的恒定磁场都属于静态电磁场。 2、静电场基本方程微分形…

Yolov5安装运行过程中出现的问题

Yolov5安装运行过程中出现的问题合集 安装问题pip 安装 requirements.txtcmd下如何退出python&#xff1f;升级numpy protobuf版本过高AttributeError: Can’t get attribute ‘SPPF’ on <module ‘models.common’ from 地址找不到图片NameError: name warnings is not de…

LabVIEW和NIUSRP硬件加快了认知无线电开发

LabVIEW和NIUSRP硬件加快了认知无线电开发 对于电视频谱&#xff0c;主用户传输有两种类型&#xff1a;广播电视和节目制作和特殊事件(PMSE)设备。广播塔的位置已知&#xff0c;且覆盖电视传输塔&#xff08;复用器&#xff09;附近的某个特定地理区域&#xff08;称为排除区域…

linux配置固定ip(两种方法)

首先刚下载的vm&#xff0c;刚创建的虚拟机&#xff0c;肯定是需要配置ip的 其次以前我的每次都是设置自动ip&#xff0c;这样每次登录都会自动获取ip地址&#xff0c;并且每次的ip都不相同。 ~方法&#xff1a; 开机登陆后 1)Cd /etc/sysconfig/network-scripts 2)Vi ifcf…

clion2020 中文版安装

一 程序安装 安装包地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1EJsmgmZcCQHoKDECkxmeaw?pwd1111 提取码&#xff1a;1111

Vue3+Vite实现工程化,插值表达式和v-text以及v-html

1、插值表达式 插值表达式最基本的数据绑定形式是文本插值&#xff0c;它使用的是"Mustache"语法&#xff0c;即 双大括号{{}} 插值表达式是将数据 渲染 到元素的指定位置的手段之一插值表达式 不绝对依赖标签&#xff0c;其位置相对自由插值表达式中支持javascript的…

Linux系统中sh脚本编写

文章目录 Linux系统中sh脚本编写1.在编写sh脚本前了解一下基本语法1.1 if语句单分支双分支多分枝 1.2 for语法 2. 自己写的demo &#xff1a;自动部署前端项目 &#xff08;自动拉取代码&#xff0c;打包&#xff0c;部署nginx&#xff09;3.定时执行 shell脚本 Linux系统中sh脚…

IO多路转接之select和poll

目录 一. IO多路转接的概念 二. 通过select实现IO多路转接 2.1 select接口 2.2 Select服务器的实现 2.3 select实现IO多路转接的优缺点 三. 通过poll实现IO多路转接 3.1 poll接口 3.2 Poll服务器的实现 3.3 poll实现IO多路转接的优缺点 四. 总结 一. IO多路转接的概念…

App测试入门

App测试基础知识 App测试&#xff0c;是指对移动应用软件&#xff08;如手机app、平板app等&#xff09;进行全面和系统的测试&#xff0c;以确保其功能、性能、安全性、稳定性、兼容性等方面能满足用户的使用需求和期望。 App常见运行系统 IOS系统&#xff1a; IOS系统是苹果公…

CUDA编程一、基本概念和cuda向量加法

目录 一、cuda编程的基本概念入门 1、GPU架构和存储结构 2、cuda编程模型 3、cuda编程流程 二、cuda向量加法实践 1、代码实现 2、代码运行和结果 有一段时间对模型加速比较感兴趣&#xff0c;其中的一块儿内容就是使用C和cuda算子优化之类一起给模型推理提速。之前一直…

适用于 Windows 的 10 个最佳视频转换器:快速转换高清视频

您是否遇到过由于格式不兼容而无法在您的设备上播放视频或电影的情况&#xff1f;您想随意播放从您的相机、GoPro 导入的视频&#xff0c;还是以最合适的格式将它们上传到媒体网站&#xff1f;您的房间里是否有一堆 DVD 光盘&#xff0c;想将它们转换为数字格式以便于播放&…

算法 LeetCode 题解 | 有效的括号

大家好&#xff0c;我是木川 一、题目描述 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。…

掌握Shell:从新手到编程大师的Linux之旅

1 shell介绍 1.1 shell脚本的意义 1.记录命令执行的过程和执行逻辑&#xff0c;以便以后重复执行 2.脚本可以批量处理主机 3.脚本可以定时处理主机 1.2 脚本的创建 #!/bin/bash # 运行脚本时候执行的环境1.3 自动添加脚本说明信息 /etc/vimrc # vim主配置文件 ~/.vimrc # 该…

Java之线程的概念及方法的学习

线程创建 方法一 直接使用Thread public class demo {public static void main(String[] args) {new Thread(){Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}.start();System.out.println(Thread.currentThread().getName());} } main…