【数据结构】知识点一:线性表之顺序表

news2024/11/6 7:35:49

内容导航

  • 一、什么是线性表?
  • 二、什么是顺序表?
    • 1、顺序表的概念
    • 2、顺序表的结构
      • a. 静态顺序表:使用定长数组存储元素。
      • b. 动态顺序表:使用动态开辟的数组存储。
  • 三、顺序表的接口实现精讲
    • 1.接口一:打印数据
    • 2.接口二:表初始化
    • 3.接口三:数据销毁
    • 4.接口四:尾插数据
    • 5.接口五:尾删数据
    • 6.接口六:头插数据
    • 7.接口七:头删数据
    • 8.接口八:容量检查
    • 9.接口九:任意位置的插入
    • 9.接口九:任意位置的删除
    • 10.接口十:任意数据的查找
  • 四、源代码分享
    • 1.SeqList.h
    • 2.SeqList.c
    • 3.test.c

一、什么是线性表?

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
在这里插入图片描述

二、什么是顺序表?

1、顺序表的概念

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

2、顺序表的结构

a. 静态顺序表:使用定长数组存储元素。

b. 动态顺序表:使用动态开辟的数组存储。

三、顺序表的接口实现精讲

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

1.接口一:打印数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

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

2.接口二:表初始化

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLInit(SL* ps1)							//初始化顺序表,全部为0
{
	assert(ps1);
	ps1->a = NULL;
	ps1->size = 0;
	ps1->capacity = 0;
}

3.接口三:数据销毁

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLDestroy(SL* ps1)							//销毁顺序表
{
	assert(ps1);
	if (ps1->a != NULL)							
	{
		free(ps1->a);
		ps1->a = NULL;
		ps1->size = 0;
		ps1->capacity = 0;
	}
}

4.接口四:尾插数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPushBack(SL* ps1, SLDataType x)			//尾插入
{
	assert(ps1);
	SLCheckCapacity(ps1);						//检查容量
	ps1->a[ps1->size] = x;
	ps1->size++;
}

5.接口五:尾删数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPopBack(SL* ps1)							//尾删除
{
	assert(ps1);
	assert(ps1->size > 0);						//有效数据为0则不需要删
	ps1->size--;
}

6.接口六:头插数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPushFront(SL* ps1, SLDataType x)		//头插入
{
	assert(ps1);
	SLCheckCapacity(ps1);						//检查容量
	//往后挪动数据
	int end = ps1->size - 1;
	while (end >= 0)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[0] = x;
	ps1->size++;
}

7.接口七:头删数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPopFront(SL* ps1)						//头删除
{
	assert(ps1);
	assert(ps1->size > 0);						//有效数据为0则不需要删
	//往前挪动数据
	int begin = 1;
	while (begin < ps1->size)
	{
		ps1->a[begin - 1] = ps1->a[begin];
		begin++;
	}
	ps1->size--;
}

8.接口八:容量检查

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLCheckCapacity(SL* ps1)					//检查空间是否充足,若否,使空间充足,头插尾插都要用到
{
	assert(ps1);
	if (ps1->size == ps1->capacity)
	{
		int NewCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps1->a, sizeof(SLDataType) * NewCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps1->a = tmp;
		ps1->capacity = NewCapacity;
	}
}

9.接口九:任意位置的插入

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLInsert(SL* ps1, int pos, SLDataType x)	//任意位置的插入
{
	assert(ps1);
	assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性
	SLCheckCapacity(ps1);						//检查容量

	//往后挪动数据
	int end = ps1->size - 1;
	while (end > pos)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[pos] = x;
	ps1->size++;
}

9.接口九:任意位置的删除

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLErase(SL* ps1, int pos)					//任意位置的删除
{
	assert(ps1);
	assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性
	//往前挪动数据
	int begin = pos+1;
	while (begin < ps1->size)
	{
		ps1->a[begin - 1] = ps1->a[begin];
		begin++;
	}
	ps1->size--;
}

10.接口十:任意数据的查找

<font color=black size=4 font face=黑体" >代码之函数的定义:

int SLFind(SL* ps1, SLDataType x)				//查找某个数据,找到返回下标,未找到返回-1
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)			//直接遍历查找
	{
		if (ps1->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

四、源代码分享

1.SeqList.h

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
typedef int SLDataType;

typedef struct SeqList
{
	SLDataType* a;							//开辟的数组地址
	int size;								//有效数据个数
	int capacity;							//容量空间的大小
}SL;

void SLPrint(SL* ps1);						//打印数据
void SLInit(SL* ps1);						//初始化顺序表,全部为0
void SLDestroy(SL* ps1);					//销毁顺序表


void SLPushBack(SL* ps1, SLDataType x);		//尾插入
void SLPushFront(SL* ps1, SLDataType x);	//头插入
void SLPopBack(SL* ps1);					//尾删除
void SLPopFront(SL* ps1);					//头删除

void SLInsert(SL* ps1, int pos, SLDataType x);	//任意位置的插入
void SLErase(SL* ps1, int pos);					//任意位置的删除

int SLFind(SL* psl, SLDataType x);				//查找某个数据,找到返回下标,未找到返回-1


2.SeqList.c

#include"SeqList.h"

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

void SLInit(SL* ps1)							//初始化顺序表,全部为0
{
	assert(ps1);
	ps1->a = NULL;
	ps1->size = 0;
	ps1->capacity = 0;
}

void SLDestroy(SL* ps1)							//销毁顺序表
{
	assert(ps1);
	if (ps1->a != NULL)							
	{
		free(ps1->a);
		ps1->a = NULL;
		ps1->size = 0;
		ps1->capacity = 0;
	}
}

void SLCheckCapacity(SL* ps1)					//检查空间是否充足,若否,使空间充足,头插尾插都要用到
{
	assert(ps1);
	if (ps1->size == ps1->capacity)
	{
		int NewCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps1->a, sizeof(SLDataType) * NewCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		ps1->a = tmp;
		ps1->capacity = NewCapacity;
	}
}
void SLPushBack(SL* ps1, SLDataType x)			//尾插入
{
	assert(ps1);
	SLCheckCapacity(ps1);						//检查容量
	ps1->a[ps1->size] = x;
	ps1->size++;
}

void SLPushFront(SL* ps1, SLDataType x)		//头插入
{
	assert(ps1);
	SLCheckCapacity(ps1);						//检查容量
	//往后挪动数据
	int end = ps1->size - 1;
	while (end >= 0)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[0] = x;
	ps1->size++;
}

void SLPopBack(SL* ps1)							//尾删除
{
	assert(ps1);
	assert(ps1->size > 0);						//有效数据为0则不需要删
	ps1->size--;
}

void SLPopFront(SL* ps1)						//头删除
{
	assert(ps1);
	assert(ps1->size > 0);						//有效数据为0则不需要删
	//往前挪动数据
	int begin = 1;
	while (begin < ps1->size)
	{
		ps1->a[begin - 1] = ps1->a[begin];
		begin++;
	}
	ps1->size--;
}

void SLInsert(SL* ps1, int pos, SLDataType x)	//任意位置的插入
{
	assert(ps1);
	assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性
	SLCheckCapacity(ps1);						//检查容量

	//往后挪动数据
	int end = ps1->size - 1;
	while (end > pos)
	{
		ps1->a[end + 1] = ps1->a[end];
		end--;
	}
	ps1->a[pos] = x;
	ps1->size++;
}

void SLErase(SL* ps1, int pos)					//任意位置的删除
{
	assert(ps1);
	assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性
	//往前挪动数据
	int begin = pos+1;
	while (begin < ps1->size)
	{
		ps1->a[begin - 1] = ps1->a[begin];
		begin++;
	}
	ps1->size--;
}

int SLFind(SL* ps1, SLDataType x)				//查找某个数据,找到返回下标,未找到返回-1
{
	assert(ps1);
	for (int i = 0; i < ps1->size; i++)			//直接遍历查找
	{
		if (ps1->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

3.test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"

void menu()
{
	printf("********************************\n");
	printf("****1、尾插数据  2、尾删数据****\n");
	printf("****3、头插数据  4、头删数据****\n");
	printf("****5、打印数据  0、退出    ****\n");
	printf("********************************\n");
}

int main()
{
	SL s;
	SLInit(&s);

	int option = 0;
	do
	{
		menu();
		printf("请输入你的选择:>");
		scanf("%d", &option);
		if (option == 1)
		{
			printf("请依次输入你的要尾插数据个数和数据:>");
			int n = 0;
			scanf("%d", &n);
			for (int i = 0; i < n; i++)
			{
				int x = 0;
				scanf("%d", &x);
				SLPushBack(&s, x);
			}
		}
		else if (option == 2)
		{
			printf("请依次输入你的要尾删数据的个数:>");
			int n = 0;
			scanf("%d", &n);
			for (int i = 0; i < n; i++)
			{
				SLPopBack(&s);
			}
		}
		else if (option == 3)
		{
			printf("请依次输入你的要头插数据个数和数据:>");
			int n = 0;
			scanf("%d", &n);
			for (int i = 0; i < n; i++)
			{
				int x = 0;
				scanf("%d", &x);
				SLPushFront(&s, x);
			}
		}
		else if (option == 4)
		{
			printf("请依次输入你的要头删数据的个数:>");
			int n = 0;
			scanf("%d", &n);
			for (int i = 0; i < n; i++)
			{
				SLPopFront(&s);
			}
		}
		else if (option == 5)
		{
			SLPrint(&s);
		}
		else if (option == 0)
		{
			break;
		}
		else
		{
			printf("无此选项,请重新输入\n");
		}
	} while (option != 0);
	SLDestroy(&s);
	return 0;
}

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

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

相关文章

Vue组件置底方法,ElementPlus布局

问题描述 在开发网页时使用了elementplus的el-container组件 组件里分成了main和footer两块&#xff0c;但是想要将两个按钮置底在容器底部遇到了困难 如下图所示&#xff0c;在网页开发者工具可见两个按钮与左侧的图片没有底部对齐 此时我的代码是这样 <el-footer>&…

探讨倒排索引Elasticsearch面试与实战:从理论到实践

在当前大数据时代&#xff0c;Elasticsearch&#xff08;以下简称为ES&#xff09;作为一种强大的搜索和分析引擎&#xff0c;受到了越来越多企业的青睐。因此&#xff0c;对于工程师来说&#xff0c;掌握ES的面试准备和实战经验成为了必备技能之一。本文将从ES的面试准备和实际…

Redis高级特性和应用(发布、订阅、Stream、慢查询、Pipeline、事务、Lua)

Redis高级特性和应用 发布和订阅 Redis提供了基于“发布/订阅”模式的消息机制&#xff0c;此种模式下&#xff0c;消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道( channel)发布消息&#xff0c;订阅该频道的每个客户端都可以收到该消息。 操作命令 Redis主要…

专为大模型训练优化,百度集合通信库 BCCL 万卡集群快速定位故障

1 集合通信对分布式训练至关重要 在分布式训练中&#xff0c;每一块 GPU 只负责处理部分模型或者数据。集群中不同 GPU 之间通过集合通信的方式&#xff0c;完成梯度同步和参数更新等操作&#xff0c;使得所有 GPU 能够作为一个整体加速模型训练。 如果有一块 GPU 在集合通…

基于BP-Adaboost的预测与分类,附MATLAB代码免费获取

今天为大家带来一期基于BP-Adaboost的预测与分类。代码中的BP可以替换为任意的机器学习算法。 原理详解 BP-AdaBoos模型先通过 AdaBoost集成算法串行训练多个基学习器并计算每个基学习 器的权重系数,接着将各个基学习器的预测结果进行线性组合,生成最终的预测结果。关于更多的原…

Ps:历史记录面板

Ps菜单&#xff1a;窗口/历史记录 Window/History 历史记录 History面板提供了对图像编辑过程中所进行更改的深入控制&#xff0c;可以让用户回溯并查看每一步操作&#xff0c;从而允许用户轻松撤销错误或比较不同的编辑效果。 ◆ ◆ ◆ 常用操作方法与技巧 “历史记录”面板…

解决 MySQL 未运行但锁文件存在的问题

查看mysql状态时&#xff0c;显示错误信息"ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists"。 解决步骤 1、检查 MySQL 进程是否正在运行 在继续之前&#xff0c;我们首先需要确定 MySQL 进程是否正在运行。我们可以使用以下命令检查…

【Mybatis】多表映射 第二期

文章目录 一、多表映射概念二、对一映射三、对多映射四、多表映射总结4.1 多表映射优化4.2 多表映射总结 一、多表映射概念 多表关系&#xff1a; 一对一一对多 | 多对一多对多 一个 客户 对应 多个订单一个订单 对应 一个客户 举例&#xff1a; 对一 实体类设计&#xff1a…

2024最新算法:鹦鹉优化算法(Parrot optimizer,PO)求解23个基准函数(提供MATLAB代码)

一、鹦鹉优化算法 鹦鹉优化算法&#xff08;Parrot optimizer&#xff0c;PO&#xff09;由Junbo Lian等人于2024年提出的一种高效的元启发式算法&#xff0c;该算法从驯养的鹦鹉中观察到的觅食、停留、交流和对陌生人行为的恐惧中汲取灵感。这些行为被封装在四个不同的公式中…

vs code更新后json文件无法识别通配符 ,编译多文件失败的解决办法

问题描述 在Mac或者LInux上&#xff0c;进行C/C相同路径下进行多文件编译时&#xff0c;之前设置好的json文件突然不能解释通配符&#xff0c;并且将带有单引号的地址传给clang&#xff0c;由于*.c被扩在单引号中&#xff0c;clang找不到文件导致失败。 如果将命令端中的指令复…

Mysql标量子查询

目录 子查询标量子查询数据准备 子查询 SQL语句中嵌套select语句&#xff0c;称为嵌套查询&#xff0c;又称子查询。 SELECT * FROM t1 WHERE column1 ( SELECT column1 FROM t2 ... );子查询外部的语句可以是insert / update / delete / select 的任何一个&…

如何将一个远程git的所有分支推到另一个远程分支上

如何将一个远程git的所有分支推到另一个远程分支上 最初有 12 个分支 执行 git remote add 远程名 远程git地址 git push 远程名 --tags "refs/remotes/origin/*:refs/heads/*"之后就变成 26个分支

Visual Studio C++项目远程断点调试客户现场程序方法

前言 程序开发一个很常见的场景&#xff0c;就是程序在自己本地部署调试明明一点问题都没有&#xff0c;但是部署到客户现场就问题百出&#xff0c;要调试起来还很困难&#xff0c;在自己本地也没有条件复现&#xff0c;很多时候只能靠日志一点点排查和猜测&#xff0c;耗费大…

基于springboot+vue的智能无人仓库管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

数据挖掘:航空公司的客户价值分析

需求分析 理解并掌握聚类分析方法&#xff0c;掌握数据的标准化&#xff0c;掌握寻找最佳聚类数&#xff0c;掌握聚类的绘图&#xff0c;掌握聚类分析的应用场景。 系统实现 实验流程分析 借助航空公司数据&#xff0c;对客户进行分类对不同类别的客户进行特征分析&#xf…

2024最新算法:美洲狮优化算法(Puma Optimizar Algorithm ,POA)求解23个基准函数(提供MATLAB代码)

一、美洲狮优化算法 美洲狮优化算法&#xff08;Puma Optimizar Algorithm &#xff0c;POA&#xff09;由Benyamin Abdollahzadeh等人于2024年提出&#xff0c;其灵感来自美洲狮的智慧和生活。在该算法中&#xff0c;在探索和开发的每个阶段都提出了独特而强大的机制&#xf…

亚信安慧AntDB:数据管理的创新先锋

在亚信安慧AntDB数据库中&#xff0c;其卓越的创新能力得以充分体现&#xff0c;其独特之处在于融合统一与实时处理这两大关键领域。AntDB以其独特的技术和理念&#xff0c;引领着数据库领域的发展潮流&#xff0c;成为众多企业和机构首选的数据库解决方案。在这个信息化时代&a…

OXK3添加字段以及Coding Block Dump

用OXK3为MSEG以及ACDOCA添加字段 SE11激活MSEG发生Coding Black Dump 用CDS视图为结构NSDM_V_MSEG添加字段 CDS相关操作详见eclipse 创建SAP CDS视图事前准备_多喝开水丶的博客-CSDN博客 SAP eclipse创建简单的CDS视图_多喝开水丶的博客-CSDN博客 SE14调整表 AbapCatalog.sql…

什么是微前端

微前端是一种web应用构建方式。 微前端在2016年ThoughtWorks Technology Radar正式被提出。微服务这个被广泛应用于服务端的技术范式扩展到前端领域。现代的前端应用的发展趋势正在变得越来越富功能化&#xff0c;富交互化&#xff0c;也就是SPA应用&#xff1b;这样越来越复杂…

Muduo库编译学习(1)

1.muduo库简介 muduo是由Google大佬陈硕开发&#xff0c;是一个基于非阻塞IO和事件驱动的现代C网络库&#xff0c;原生支持one loop per thread这种IO模型&#xff0c;该库只支持Linux系统&#xff0c;网上大佬对其褒贬不一&#xff0c;作为小白用来学习就无可厚非了。 git仓库…