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

2023-11-17

一.线性表

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;
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构基础:2.顺序表。 的相关文章

  • 算法分析与设计作业4:归并排序

    1 问题 二分归并排序 对n个不同的数构成的数组A 1 n 进行排序 其中n 2 k 标题 2 解析 先将杂乱的数字两两分组 对两个数字比较大小进行排序 再将两个排序好的数组按顺序归并 依此循环k次 直至所有小数组被归并为完整的大数组 3
  • 组合逻辑毛刺消除(竞争冒险)

    一 毛刺产生的原因 信号在 IC FPGA 器件中通过逻辑单元连线时 是存在延时的 延时的大小不仅和连线的长短和逻辑单元的数目有关 而且也和器件的制造工艺 工作环境等有关 因此 信号在器件中传输的时候 所需要的时间是不能精确估计的 当多路信

随机推荐

  • tauri打包慢:解决tauri的打包慢以及超时的方法

    打包的命令 yarn tauri build 打包的时候 会下载一个依赖包 由于这个依赖包是在github上下载的 因此会很慢或者超时 可以将这个地址 https github com wixtoolset wix3 releases do
  • STM32在线升级 (IAP)

    来自QQ群 Linux 技术分享 311078264 打开链接加入QQ群 https jq qq com wv 1027 k 5Gr3bAx 此文档由elikang整理 为了文章简单直接 许多细节未能在文章中体现 如有疑问请进群讨论 STM
  • GPT-4 VS GPT-3.5!你需要升级plus版本吗?

    GPT 4和 GPT 3 5语言模型在前沿技术的推动下 都具备了相当出色的自然语言生成能力 鉴于GPT 4正式发布的消息已经引发了不小的关注 本文将从完善度测试 推理能力测试 创造力测试三个角度探讨两者的区别和优劣 为您提供实用的指导 帮助
  • u-input改变输入框内的字体样式

    编辑uview的组件input 由于我的项目背景是蓝色 因此要改变input组件的字体颜色 刚开始我的思路是 直接找到u input组件的class 但是这样设置的话 会导致所有的input内文字都变成我设置的颜色 综合网上的信息 我的处理
  • 刷脸支付也将进一步助力生活生产智能化

    支付宝和微信支付竞相发起 扫货节 和 智慧生活日 活动 不约而同地聚焦刷脸支付 用刷脸支付立减 免单的方式鼓励广大消费者投入刷脸支付的怀抱 毫无疑问 刷脸支付是大数据和人工智能时代的产物 同时 刷脸支付也将进一步助力生活生产智能化 为智慧营
  • 《HTML标签》〈ul〉〈ol〉〈li〉的使用

    li 标签定义和用法 li li 标签定义列表项目 li li 标签可用在有序列表 ol 和无序列表 ul 中 ol 标记 称为有序列表 编号列表标记 其功能是将文字段落向内缩进 并在段落的每个项目前面加上1 2 3 有顺序的数字 ol 标
  • Could not find com.android.support:appcompat-v7:23.1.1 问题解决

    allprojects repositories jcenter maven url https maven google com 添加这个就可以
  • 毛坯装修知识

    硬装指的是装修阶段必须完成的项目 而且一旦完成 很难改动 软装基本就是搬家时能够搬走的那些东西 最简单的区别就是 把屋子倒过来 会掉下来的就是软装 掉不下来的就是硬装 家具电器 窗帘布艺 装饰挂画等等都算软装 插座 门 地板瓷砖这些 更换起
  • 融合零样本学习和小样本学习的弱监督学习方法综述

    融合零样本学习和小样本学习的弱监督学习方法综述 人工智能技术与咨询 来源 系统工程与电子技术 作者潘崇煜等 摘 要 深度学习模型严重依赖于大量人工标注的数据 使得其在数据缺乏的特殊领域内应用严重受限 面对数据缺乏等现实挑战 很多学者针对数据
  • 小程序之坑---input自动获取焦点

    项目 taro3 vue3 taro ui vue3 方法一 taro ui vue3的input组件的autoFocus focus无效 方法二 原生input组件的auto focus在这个环境下也无效 但是在原生项目中有效 方法三 通
  • js里document的用法

    document write 动态向页面写入内容 document createElement Tag 创建一个html标签对象 document getElementById ID 获得指定ID值的对象 document getEleme
  • mysql 两个时间相减返回年、月、日、时、分、秒

    select timestampdiff 变量 开始时间 结束时间 变量 year 年 month 月 day 天 hour 小时 minute 分钟 second 秒 例如
  • 由Vite读音引发的英语颠覆

    前段时间出了个项目Vite 被读成va t 结果后面发现是读vi t 后面又引出了height的读音 我们有些人读he t 有些人读ha t 结果是读ha t 我也是读了20年的he t 因为有个weight是读we t的 所以想当然的以为
  • 对象和字符串之间的相互转换

    原文链接 对象和字符串之间的相互转换 编程屋 相关依赖
  • Python——12306图片验证码

    本次爬虫 我们来模拟一下12306的验证码验证 本次练习用到的模块 requests re base64 urllib3 第一步 按F12查看验证码图片的信息 提取URL https kyfw 12306 cn passport captc
  • 前端页面之间url传参

    function getUrlParam name var reg new RegExp name var r window location search substr 1 match reg ECMAScript v3 已从标准中删除了
  • 如何设置office2003为默认打开方式

    如何设置office2003为默认打开方式 当系统同时安装 office 2003和 office 2007 或2010 两个版本的 office办公软件的时候 双击打开一个office文档 Word Excel Powerpoint 默认
  • 【CV with Pytorch】第 10 章 :计算机视觉的可解释人工智能

    大多数机器学习和深度学习模型都缺乏解释和解释结果的方法 由于深度学习模型的动态特性和不断增加的最先进模型 当前的模型评估基于准确度分数 这使得机器学习和深度学习成为黑盒模型 这导致对应用模型缺乏信心 对生成的结果缺乏信任 有多个库可以帮助我
  • 刷题统计(蓝桥杯)

    刷题统计 问题描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛 他计划周一至周五每天 做 a 道题目 周六和周日每天做 b 道题目 请你帮小明计算 按照计划他将在 第几天实现做题数大于等于 n 题 输入格式 输入一行包含三个整数 a b 和
  • 数据结构基础:2.顺序表。

    顺序表的介绍和实现 一 线性表 1 基本概念 二 顺序表 1 基本概念 分类 1 静态顺序表 分类 2 动态顺序表 2 动态顺序表的功能接口的实现 0 顺序表打印 1 初始化和删除 2 尾插尾删 3 头插头删 4 任意位置插入删除 5 查找