数据结构--动态顺序表

news2024/12/26 0:40:15

文章目录

  • 线性表
  • 动态顺序表
    • 数组与顺序表
  • 接口实现
    • 初始化:
    • 尾插:
    • 尾删
    • 头插
    • 头删
    • 指定位置插入
    • 指定位置删除
    • 查找
    • 摧毁
  • 完整代码

线性表

线性表是数据结构中最基本、最简单也是最常用的一种数据结构。线性表是指由n个具有相同数据类型的元素组成的有限序列

线性表分为顺序表和链表两种实现方式。

  1. 顺序表
    顺序表是线性表的一种实现方式,它在计算机内存中以数组的形式保存数据元素。顺序表的特点是元素在内存中是连续存储的,通过索引可以直接访问元素,因此具有较快的随机访问速度。但是顺序表的长度是固定的,需要提前申请足够的内存空间,并且插入和删除元素时需要移动其他元素,效率较低。
    在这里插入图片描述

  2. 链表
    链表是线性表的另一种实现方式,它通过指针将多个节点串联起来。每个节点包含元素和指向下一个节点的指针,所以链表的内存分布可以是离散的。链表的优点是可以动态地分配内存,插入和删除操作只需要修改指针,效率较高。但是链表的访问速度比较慢,需要遍历节点找到目标位置。
    在这里插入图片描述

本章主要介绍的是顺序表。

动态顺序表

顺序表分为静态顺序表和动态顺序表;

静态顺序表是用定长数组来进行存储元素;
在这里插入图片描述
动态顺序表是利用动态存储开辟的数组:
在这里插入图片描述

数组与顺序表

顺序表和数组在某种程度上可以说是相似的,因为顺序表的基本实现就是数组。顺序表是对数组的一种封装,它在数组的基础上提供了更加灵活的内存管理方式,使得插入、删除等操作更加高效。

接口实现

我们要将函数都包含在一个头文件中,然后用一个源文件来对函数的实现;
结构

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTypeData;

typedef struct SeqList
{
	SLTypeData* a;
	int size;  //有效个数
	int capacity;  //空间大小

}SL;

初始化:

void SLInit(SL* ps)
{
	assert(ps);

	ps->a = (SLTypeData*)malloc(sizeof(SLTypeData) * 4);
	if (ps->a == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;
}

对数组先开辟4个空间,然后判断是否开辟成功,成功就对size和容量进行初始化赋值;

尾插:

void AddCapacity(SL* ps)
{
	assert(ps);

	SLTypeData* cmp = (SLTypeData*)realloc(ps->a, sizeof(SLTypeData) * (ps->capacity + 3));
	if (cmp == NULL)
	{
		perror("realloc failed");
		exit(-1);
	}
	ps->a = cmp;
	ps->capacity += 3;
}
void SLPushBack(SL* ps, SLTypeData x)
{
	//满需要扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}

	//开始尾插
	ps->a[ps->size] = x;
	ps->size++;
}

在这里,由于还有头插和位置插入,所以就写一个函数来进行增加容量;每次容量增加3;尾插只需要在size下标进行赋值,最后再把size++即可;

我们写一个打印函数验证一下:

void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

然后在主函数中加以验证:

#include"SeqList.h"

int main()
{
	SL test;
	SLInit(&test);
	SLPushBack(&test, 1);
	SLPushBack(&test, 2);
	SLPushBack(&test, 3);
	SLPushBack(&test, 4);
	SLPushBack(&test, 5);
	SLPrint(&test);
	return 0;
}

在这里插入图片描述

尾删

void SLPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushBack(&test, 1);
	SLPushBack(&test, 2);
	SLPushBack(&test, 3);
	SLPushBack(&test, 4);
	SLPushBack(&test, 5);
	SLPrint(&test);
	SLPopBack(&test);
	SLPrint(&test);
	return 0;
}

在这里插入图片描述

头插

void SLPushFront(SL* ps, SLTypeData x)
{
	assert(ps);

	//满扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}
	//往后移
	for (int i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i-1];
	}
	//头插
	ps->a[0] = x;
	ps->size++;
}

这里要插入需要对当前数组进行挪移,给第一个元素腾出空间存储;

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	
	SLPrint(&test);
	return 0;
}

在这里插入图片描述

头删

void SLPopFront(SL* ps)
{
	assert(ps);

	//判断
	assert(ps->size > 0);
	//左移
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	//size减1
	ps->size--;

}

头一个元素删完之后,需要将后面元素向前移动;最后将size–;

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	SLPopFront(&test);
	SLPrint(&test);
	return 0;
}

在这里插入图片描述

指定位置插入

//起始位置为1,例如pos=1,那么就是在下标为0的位置插入
void SLInsert(SL* ps, int pos, SLTypeData x)
{
	assert(ps);
	assert(pos > 0 && pos <= ps->size + 1); //指定pos范围
	//满扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}
	//位置后移
	for (int i = ps->size; i > pos - 1; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	//插入
	ps->a[pos - 1] = x;
	ps->size++;
}

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	SLInsert(&test, 3, 88);
	SLPrint(&test);
	
	return 0;
}

在这里插入图片描述

指定位置删除

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos > 0 && pos <= ps->size);//指定pos范围
	//左移
	for (int i = pos - 1; i < ps->size-1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	SLInsert(&test, 3, 88);
	SLPrint(&test);
	SLErase(&test, 4);
	SLPrint(&test);
	
	return 0;
}

在这里插入图片描述

查找

查找对应的元素,如果有多个元素一样,返回的是最左边的元素;
返回的初始位置为1,例如下标为0,那么返回位置为1;

int SLFind(SL* ps, SLTypeData x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i+1;
		}
	}
	return -1;
}

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	int pos = SLFind(&test, 3);
	printf("3的位置是%d", pos);
	
	return 0;
}

在这里插入图片描述

摧毁

void SLDestory(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

验证:

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	SLDestory(&test);
	SLPrint(&test);
	
	return 0;
}

在这里插入图片描述

完整代码

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//动态顺序表
typedef int SLTypeData;

typedef struct SeqList
{
	SLTypeData* a;
	int size;  //有效个数
	int capacity;  //空间大小

}SL;


void SLInit(SL* ps);//顺序表初始化
void SLDestory(SL* ps);//顺序表摧毁
void SLPushBack(SL* ps, SLTypeData x);//尾插
void SLPopBack(SL* ps);//尾删
void SLPushFront(SL* ps, SLTypeData x);//头插
void SLPopFront(SL* ps);//头删
int SLFind(SL* ps, SLTypeData x);//查找
void SLInsert(SL* ps, int pos, SLTypeData x);//插入
void SLErase(SL* ps, int pos);//删除
void SLPrint(SL* ps);//打印

SeqList.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void SLInit(SL* ps)
{
	assert(ps);

	ps->a = (SLTypeData*)malloc(sizeof(SLTypeData) * 4);
	if (ps->a == NULL)
	{
		perror("malloc failed");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;
}

void SLDestory(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

//满扩容
void AddCapacity(SL* ps)
{
	assert(ps);

	SLTypeData* cmp = (SLTypeData*)realloc(ps->a, sizeof(SLTypeData) * (ps->capacity + 3));
	if (cmp == NULL)
	{
		perror("realloc failed");
		exit(-1);
	}
	ps->a = cmp;
	ps->capacity += 3;
}
void SLPushBack(SL* ps, SLTypeData x)
{
	//满需要扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}

	//开始尾插
	ps->a[ps->size] = x;
	ps->size++;
}

void SLPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

void SLPushFront(SL* ps, SLTypeData x)
{
	assert(ps);

	//满扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}
	//往后移
	for (int i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i-1];
	}
	//头插
	ps->a[0] = x;
	ps->size++;
}

void SLPopFront(SL* ps)
{
	assert(ps);

	//判断
	assert(ps->size > 0);
	//左移
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	//size减1
	ps->size--;

}

int SLFind(SL* ps, SLTypeData x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i+1;
		}
	}
	return -1;
}

void SLInsert(SL* ps, int pos, SLTypeData x)
{
	assert(ps);
	assert(pos > 0 && pos <= ps->size + 1);
	//满扩容
	if (ps->size == ps->capacity)
	{
		AddCapacity(ps);
	}
	//位置后移
	for (int i = ps->size; i > pos - 1; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	//插入
	ps->a[pos - 1] = x;
	ps->size++;
}

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos > 0 && pos <= ps->size);
	assert(pos > 0);
	//左移
	for (int i = pos - 1; i < ps->size-1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");

}

test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

int main()
{
	SL test;
	SLInit(&test);
	SLPushFront(&test, 1);
	SLPushFront(&test, 2);
	SLPushFront(&test, 3);
	SLPushFront(&test, 4);
	SLPushFront(&test, 5);
	SLPrint(&test);
	SLDestory(&test);
	SLPrint(&test);
	
	return 0;
}

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

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

相关文章

Kubernetes (k8s)理论介绍

一&#xff1a;K8s 简介 1、K8s作用 2、K8s 来历 3、为什么要用 K8S? 4、Kubernetes 功能 二&#xff1a;Kubernetes 集群架构与组件 1、Kubernetes 集群架构与组件 2、核心组件 -Master 组件 &#xff08;1&#xff09;Kube-apiserver &#xff08;2&#xff09;Kube…

Wiki知识库项目-全流程笔记

第一章 第二章 2.1本章项目流程 2.2创建springboot项目 2.2.1修改springboot的版本号为 2.4.0 2.2.3将代码交给git进行管理 2-5修改日志样式 2.5.1将springboot项目打印日志样式进行修改。创建logback-spring.xml文件夹&#xff0c;文件与application.xml文件位置并列。 &l…

图书借阅系统 SSM框架

步骤一&#xff1a;创建数据库、表 步骤二&#xff1a;创建工程、包、pom依赖 步骤三&#xff1a;web.xml 步骤四&#xff1a;applicationContext.xml 步骤五&#xff1a;mybatis-config.xml 步骤六&#xff1a;实体类 步骤七&#xff1a;BookInfoMapper 步骤八&#xff1a; 步…

小白到运维工程师自学之路 第六十一集 (docker容器的操作)

1、创建容器与运行容器 docker create -it nginx /bin/bash -i 让容器的输入保持打开 -t 让Docker 分配一个伪终端 -d 守护进程形式运行 使用docker create 命令创建新容器后会返回一个唯一的ID 2、查看运行状态 docker ps -a 可以使用docker ps 命令来查看所有容器的运行状态…

未能加载文件或程序集“System.CodeDom, Version=4.0.2.0。。。或它的某一个依赖项。系统找不到指定的文件

winform未能加载文件或程序集“System.CodeDom, Version4.0.2.0, Cultureneutral, PublicKeyTokencc7b13ffcd2ddd51”或它的某一个依赖项。系统找不到指定的文件。 触发原因解决方法 触发原因 在NuGet中安装IronPython时&#xff0c;由于一直提示缺少依赖&#xff0c;所以在安…

长度最小的子数组_力扣209

文章目录 题目描述法一 滑动窗口法 题目描述 法一 滑动窗口法 int minSubArrayLen(int target, vector<int>&nums){int n nums.size();int cnt INT_MAX;int start0, end0, sum0;while(end<n){sum nums[end];while(sum>target){cnt min(cnt, end-start1);su…

智慧灯杆四大应用场景

智慧灯杆是一种通过集成先进技术和智能系统的道路照明设施。它不仅具备传统灯杆的基本功能&#xff0c;还具有灯具、传感器、通信设备、监控摄像头等多个功能模块。可以实现智能照明、环境监测、安全监控、交通管理等多种功能&#xff0c;为城市的智慧化建设和市民的生活提供更…

html:去除input/textarea标签的拼写检查

默认情况下&#xff0c;textarea 会启动拼写和语法检查&#xff0c;表现效果就是单词拼写错误会出现红色下划线提示 <textarea></textarea>效果 有时&#xff0c;我们并不需要拼写检查&#xff0c;可以通过配置属性spellcheck"false" 去除拼写和语法检…

【打表】ccpc 2022威海 G

Problem - G - Codeforces 题意&#xff1a; 思路&#xff1a; 这种题大概率只能打表 把gcd(kx^x,x)的值打出来&#xff0c;可以发现是个循环节 Code&#xff1a; #include <bits/stdc.h>#define int long longusing namespace std;const int mxn1e610; const int mx…

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)

因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护&#xff0c;固采用 PhpSpreadsheet 效果如图&#xff1a; 第一步&#xff1a;首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下&#xff1a; composer r…

【Linux命令200例】rm用来删除文件或目录(谨慎使用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…

1.3 网络空间安全政策与标准

数据参考&#xff1a;CISP官方 目录 网络安全国家战略网络安全标准体系网络安全等级保护网络安全职业道德 一、网络安全国家战略 1、国家指导政策 《中华人民共和国网络安全法》&#xff1a;该法律于2016年出台&#xff0c;2017年6月1日正式生效。它是中国网络安全领域的基…

Kylin v10基于cephadm工具离线部署ceph分布式存储

1. 环境&#xff1a; ceph&#xff1a;octopus OS&#xff1a;Kylin-Server-V10_U1-Release-Build02-20210824-GFB-x86_64、CentOS Linux release 7.9.2009 2. ceph和cephadm 2.1 ceph简介 Ceph可用于向云平台提供对象存储、块设备服务和文件系统。所有Ceph存储集群部署都从…

基于Spring Boot的美食分享网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的美食分享网站设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java springboot…

数控机床主轴品牌选择及选型,如何维护和保养?

数控机床主轴品牌选择及选型&#xff0c;如何维护和保养&#xff1f; 数控机床是一种高精度、高效率、高自动化的机床。其中&#xff0c;主轴是数控机床的核心部件&#xff0c;承担着转动工件、切削加工的任务&#xff0c;决定了加工的转速、切削力度和加工效率。因此&#xff…

C++入门教程||C++地图用法

C地图用法 C 中 map 提供的是一种键值对容器&#xff0c;里面的数据都是成对出现的&#xff0c;如下图&#xff1a;每一对中的第一个值称之为关键字&#xff08;key&#xff09;&#xff0c;每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值。在一些程序中建立一…

最难用的鼠标键、设置半天、反人类逻辑(罗技)

目的&#xff1a;高效设置罗技鼠标键&#xff0c;提高复制粘贴效率 准备软件&#xff1a;Logitech G HUB – Logitech 支持 下载 1、右上角&#xff0c;点击箭头、点击管理配置文件 2、左下角、点击加号&#xff0c;创建配置文件“办公” 3、点击办公 4、右上角选择“办公”…

蓝桥云课ROS机器人旧版实验报告-01入门

项目名称 实验一 ROS[Kinetic/Melodic/Noetic]入门 成绩 设计要求&#xff1a; 机器人操作系统安装、虚拟机、Docker、嵌入式系统 实验记录&#xff08;70分&#xff09; 1.以 $ 开头的行是终端命令。 - 要打开一个新终端 → 使用快捷键 ctrlaltt。 - 要在现有终端内…

Mac端口扫描工具

端口扫描工具 Mac内置了一个网络工具 网络使用工具 按住 Command 空格 然后搜索 “网络实用工具” 或 “Network Utility” 即可 域名/ip转换Lookup ping功能 端口扫描 https://zhhll.icu/2022/Mac/端口扫描工具/ 本文由 mdnice 多平台发布

生成测试报告就万事大吉了吗?NO,升职加薪就差这一步啦!- 04(非常详细,非常实用)

简介 上一篇生成测试报告&#xff0c;小伙伴们和童鞋们就又问道&#xff0c;测试报告已经生成了&#xff0c;怎么发送给相关的负责人了&#xff1f;小伙伴们和童鞋们不要着急&#xff0c;慢慢给你道来&#xff0c;心急吃不了热豆腐哈。这些小伙伴们的表现还是不错的&#xff0c…