数据结构(初阶2.顺序表)

文章目录

一、线性表

二、顺序表

 2.1 概念和结构

 2.2 分类

    2.2.1 静态顺序表

    2.2.2 动态顺序表

 2.3动态顺序表的实现

  1.SeqList.h

  2.SeqList.c

    打印顺序表

    初始化

    销毁

    增容

    尾插

    头插

    在指定位置之前插入数据

    尾删

    头删

    在指定位置删除数据

  3.test.c


一、线性表

线性表( linear list )是n个具有相同特性的数据元素的有限序列。
线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。
  • 逻辑结构(认为想象出来的数据的组织形式):都是线性的
  • 物理结构(数据在内存上的存储形式):不一定是线性的

二、顺序表

2.1 概念和结构

概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤               数组存储。
那么数组和顺序表的区别是什么?
下面可以进行一个很形象的类比:
  • 顺序表是对数组进行封装:结构体
  • 定义已经知道数组的大小:    int arr【3】= {1,2,3};
  • 定义未知道数组的大小:        int*arr;

2.2 分类

2.2.1 静态顺序表

上图中可以发现我们重新定义了 typedef int SLDataType,为什么?

比如当我们在测试代码中有 100000行代码,1000+会定义整型变量 int,当要把这 1000+ 的代码部分改成 char 类型时,如果逐个将这些代码找出一句句修改会非常麻烦而且工作量巨大;              而当 typedef int SLDataType之后 ,我们只需将其改成 typedef char SLDataType ,遍能一键替换为 char 或者想要修改的位置。

2.2.2 动态顺序表

2.3动态顺序表的实现

(注意:1.当我们每实现一个方法之后须测试一下,切记写完所有方法才测试,避免出现差错;

             2.在调用过程中分清传值和传址的区别;

                传值:形参是实参的值的拷贝,实参和形参指向的是两块不同的地址,但保存的数据是                             一样的

                传址:形参指向的是实参指向的地址) 

1.SeqList.h

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

//定义动态顺序表结构
typedef int SLDatatype;

typedef struct SeqList {
	SLDatatype* arr;
	int capacity; //空间大小
	int size;     //有效数据个数
}SL;

//typedef struct SeqList SL;

//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);

//打印顺序表
void SLPrint(SL* ps);

//插入数据
void SLPushBack(SL* ps, SLDatatype x);
void SLPushFront(SL* ps, SLDatatype x);

//删除
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);

//在指定位置之前插入数据
void SLInsert(SL* ps, SLDatatype x, int pos);
//删除指定位置的数据
void SLErase(SL* ps, int pos);

 

2.SeqList.c 

  • 打印顺序表
void SLPrint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}
  • 初始化  
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
  • 销毁
void SLDestory(SL* ps)
{
	if (ps->arr != NULL)
	{
		free(ps->arr);

	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
  •  增容

当size == capacity 时,说明顺序表满了,空间不足,先增容,再插入;

增容一般是成倍数的增加(增容的操作本身就有一定的程序性能的消耗,若频繁的增容会导致程序效率底下),所以 ”一次增容一个就没有空间浪费“ 这种说法是错误的。 

增容分两种情况: 1.连续空间足够,直接扩容 

                              2.连续空间不够,1)重新找一块地址,分配足够的内存 

                                                          2)拷贝数据到新的地址 

                                                          3)销毁就地址 

 

void SLCheckCapacity(SL* ps)
{
	//判断空间是否充足
	if (ps->size = ps->capacity)
	{
		//增容//0*2 = 0
		//若capacity为0,给个默认值,否则×2倍
		int newCapacity = ps->arr == 0 ? 4 : 2 * ps->capacity;
		SLDatatype* tmp = (SLDatatype*)realloc(ps->arr, newCapacity * sizeof(SLDatatype));
		if (tmp = NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}
  • 尾插 

空间充足:将数据插入 size 指向的位置,size++;

void SLPushBack(SL* ps, SLDatatype x)
{
	assert(ps);//等价于assert(ps != NULL)


	SLCheckCapacity(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}
  • 头插
void SLPushFront(SL* ps, SLDatatype x)
{
	assert(ps);

	//判断空间是否足够
	SLCheckCapacity(ps);

	//整体数据往后移一位,从后往前移
	for (int i = ps->size;i >0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}

	//将数据插入下标为0的位置
	ps->arr[0] = x;
}
  • 在指定位置之前插入数据
void SLInsert(SL* ps, SLDatatype x, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//       头插          尾插 

	//pos及以后的数据整体向后移动一位,从后往前移,与头插的方法类似
	for (int i =ps->size ; i>pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}

	//将数据插入下标为pos的位置
	ps->arr[pos] = x;
	ps->size++; //不要忘记这一步
}
  • 尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表为空,不可删除

	ps->size--;
}
  • 头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);//顺序表为空,不可删除

	//数据整体向前移动一位,从前往后移
	for (int i = 0; i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;

}
  • 在指定位置删除数据
void SLDelete(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size);//顺序表为空,不可删除
	assert(pos >= 0 && pos <= ps->size);
	//       头删          尾删 

	//pos及以后的数据整体向前移动一位,从前往后移,与SLInsert的方法类似
	for (int i = pos; i < ps->size; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

 3.test.c

#include "SeqList.h"

void SLtest01()
{
	SL s;
	SLInit(&s);

	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 10);
	SLPushBack(&s, 11);
	SLPushBack(&s, 12);
	printf("尾插后的数据:");
	SLPrint(&s);

	printf("头插后的数据:");
	SLPushFront(&s, 4);
	SLPrint(&s);

	printf("在下标为2的位置插入9后的数据:");
	SLInsert(&s, 9, 2);
	SLPrint(&s);

	printf("尾删后的数据:");
	SLPopBack(&s);
	SLPrint(&s);

	printf("头插后的数据:");
	SLPopFront(&s);
	SLPrint(&s);

	printf("删除下标为3的数据:");
	SLDelete(&s, 3);
	SLPrint(&s);

	SLDestroy(&s);
}

int main()
{
	SLtest01();	
	return 0;
}

未完待续~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浏览器中js外挂脚本的执行方式

1、开发工具控制台交互执行 网页中按F12打开开发者工具&#xff0c;选择“控制台”&#xff0c;键入js脚本命令回车执行&#xff0c;适用于临时使用脚本逻辑简单的场景&#xff0c;实例如下&#xff1a; // 获取网页元素的文本脚本 var elem document.getElementById("…

开发个人Go-ChatGPT–6 OpenUI

开发个人Go-ChatGPT–6 OpenUI Open-webui Open WebUI 是一种可扩展、功能丰富且用户友好的自托管 WebUI&#xff0c;旨在完全离线运行。它支持各种 LLM 运行器&#xff0c;包括 Ollama 和 OpenAI 兼容的 API。 功能 由于总所周知的原由&#xff0c;OpenAI 的接口需要密钥才…

Zabbix Sia Zabbix 逻辑漏洞(CVE-2022-23134)

前言 CVE-2022-23134是一个中等严重度的漏洞&#xff0c;影响Zabbix Web前端。这个漏洞允许未经身份验证的用户访问setup.php文件的某些步骤&#xff0c;这些步骤通常只对超级管理员开放。利用这个漏洞&#xff0c;攻击者可以通过跳过某些步骤来重新配置Zabbix前端&#xff0c…

Qt 线程同步机制 互斥锁 信号量 条件变量 读写锁

qt线程同步 Qt提供了丰富的线程同步机制来帮助开发者更高效和安全地进行多线程编程。其主要包括: QMutex:为共享数据提供互斥访问能力,避免同时写入导致的数据冲突。利用lock()/unlock()方法实现锁定和解锁。 QReadWriteLock:读写锁,允许多个读线程同时访问,但写操作需要独占…

Java面试八股之MySQL中int(10)和bigint(10)能存储读的数据大小一样吗

MySQL中int(10)和bigint(10)能存储读的数据大小一样吗 在MySQL中&#xff0c;int(10)和bigint(10)的数据存储能力并不相同&#xff0c;尽管括号内的数字&#xff08;如10&#xff09;看起来似乎暗示着某种关联&#xff0c;但实际上这个数字代表的是显示宽度&#xff0c;而不是…

基于信号量的生产者消费者模型

文章目录 信号量认识概念基于线程分析信号量信号量操作 循环队列下的生产者消费者模型理论认识代码部分 信号量 认识概念 信号量本质: 计数器 它也叫做公共资源 为了线程之间,进程间通信------>多个执行流看到的同一份资源---->多个资源都会并发访问这个资源(此时易出现…

Python OpenCV 教学取得视频资讯

这篇教学会介绍使用OpenCV&#xff0c;取得影像的长宽尺寸、以及读取影像中某些像素的颜色数值。 因为程式中的OpenCV 会需要使用镜头或GPU&#xff0c;所以请使用本机环境( 参考&#xff1a;使用Python 虚拟环境) 或使用Anaconda Jupyter 进行实作( 参考&#xff1a;使用Anaco…

关于.NETCORE站点程序部署到nginx上无法访问静态文件和无法正确生成文件的问题解决过程。

我的netcore6项目&#xff0c;部署到IIS的时候&#xff0c;生成报告时&#xff0c;需要获取公司LOGO图片放到PDF报告文件中&#xff0c;这时候访问静态图片没有问题。 然后还有生成邀请二维码图片&#xff0c;这时候动态创建图片路径和图片也没有问题&#xff0c;可以在站点的…

14-58 剑和诗人32 - 使用矢量数据库增强 LLM 应用程序

GPT-4、Bloom、LaMDA 等大型语言模型 (LLM) 在生成类似人类的文本方面表现出了令人印象深刻的能力。然而,它们在事实准确性和推理能力等方面仍然面临限制。这是因为,虽然它们的基础是从大量文本数据中提取统计模式,但它们缺乏结构化的知识源来为其输出提供依据。 最近,我们…

Python:安装/Mac

之前一直陆陆续续有学python&#xff01;今天开始&#xff01;正式开肝&#xff01;&#xff01;&#xff01; 进入网站&#xff1a;可能会有点慢&#xff0c;多开几个网页 https://www.python.org 点击下载&#xff0c;然后进入新的页面&#xff0c;往下滑 来到File&#xff0…

成为编程大佬!!——数据结构与算法(1)——算法复杂度!!

前言&#xff1a;解决同一个程序问题可以通过多个算法解决&#xff0c;那么要怎样判断一个算法的优劣呢&#xff1f;&#x1f914; 算法复杂度 算法复杂度是对某个程序运行时的时空效率的粗略估算&#xff0c;常用来判断一个算法的好坏。 我们通过两个维度来看算法复杂度——…

c++ 多边形 xyz 数据 获取 中心点方法

有需求需要对。多边形 获取中心点方法&#xff0c;绝大多数都是 puthon和java版本。立体几何学中的知识。 封装函数 point ##########::getCenterOfGravity(std::vector<point> polygon) {if (polygon.size() < 2)return point();auto Area [](point p0, point p1, p…

leetcode--从中序与后序遍历序列构造二叉树

leeocode地址&#xff1a;从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder …

Oracle基础以及一些‘方言’(二)

1、Oracle的查询语法结构 Oracle 的单表查询的语法结构&#xff1a; SELECT 1 FROM 2 WHERE 3 GROUP BY 4 HAVING 5 ORDER BY 6 其每个关键词的功能与MySQL中的功能已知&#xff0c;不过分页查询的关键词 limit 并不在Oracle的语法结构中。伪列&#xff1a; 在 Oracle 的表的使…

资料分析笔记整理

提升技巧多做题、少动笔、多分析 资料分析认识 国考一般20题(24~28分钟) 统计材料的类型包括单纯的文字、表格、图形以及由这些元素组成的复合类型材料 文字性材料:(30~60秒) 多段落型文字材料(时间、关键词、结构) 孤立段落文字材料(时间、关键词、标点[。;]) 表…

Linux 利用命名空间创建一个自己的“容器“

Linux 利用命名空间创建一个自己的"容器" 前置条件 创建一个目录存放容器mkdir /myapp准备静态编译busybox&#xff0c;操作系统自带的往往是依赖动态库的(本文使用的debian apt install busybox-static) 开始 使用unshare起一个独立命名空间.# 进入后/myapp目录…

如何理解http与https协议,他们有什么区别?

写在前面的话&#xff0c;关于 HTTP 和 HTTPS 的问题&#xff0c;常常会被很多学习者忽略&#xff0c;HTTP、HTTPS 不就是网址的开头吗&#xff0c;有啥好了解的&#xff0c;浏览器的引擎实现了这个协议&#xff0c;在开发关系不大&#xff0c;但想要深入一些理解数据传输原理&…

《植物大战僵尸杂交版》2.2版本:全新内容与下载指南

《植物大战僵尸杂交版》2.2版本已经火热更新&#xff0c;带来了一系列令人兴奋的新玩法和调整&#xff0c;为这款经典的塔防游戏注入了新的活力。如果你是《植物大战僵尸》系列的忠实粉丝&#xff0c;那么这个版本绝对值得你一探究竟。 2.2版本更新亮点 新增看星星玩法 这个新…

HarmonyOS鸿蒙DevEco Studio无法连接本地模拟器

使用DevEcoStudio 5.0.3.403版本 发现无法选择模拟器 解决方法&#xff1a; 1、打开模拟器 2、关闭DevEco Studio&#xff0c;&#xff08;不要关闭模拟器&#xff09; 3、重新打开DevEco Studio。

效果惊人!LivePortrait开源数字人技术,让静态照片生动起来

不得了了,快手已经不是众人所知的那个短视频娱乐平台了。 可灵AI视频的风口尚未过去,又推出了LivePortrait--开源的数字人项目。LivePortrait让你的照片动起来,合成逼真的动态人像视频,阿里通义EMO不再是唯一选择。 让图像动起来 LivePortrait 主要提供了对眼睛和嘴唇动作的…