【数据结构(顺序表)】

一、什么是数据结构?

数据结构是由“数据”和“结构”两词组合而来。
什么是数据?常见的数值1、2、3、4.....、教务系统里保存的用户信息(姓名、性别、年龄、学历等等)、网页里肉眼可以看到的信息(文字、图片、视频等等),这些都是数据
什么是结构?
当我们想要使用大量使用同⼀类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在⼀起,结构也可以理解为组织数据的方式。
想要找到草原上名叫“咩咩”的羊很难,但是从羊圈里找到1号羊就很简单,羊圈这样的结构有效将
羊群组织起来。
概念:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在⼀种或多种特定关系
的数据元素的集合。数据结构反映数据的内部构成,即数据由那部分构成,以什么方式构成,以及数据元素之间呈现的结构。
总结:
1)能够存储数据(如顺序表、链表等结构)
2)存储的数据能够方便查找

二、为什么需要数据结构?

如图中所示,不借助排队的方式来管理客户,会导致客户就餐感受差、等餐时间长、餐厅营业混乱等情况。同理,程序中如果不对数据进行管理,可能会导致数据丢失、操作数据困难、野指针等情况。通过数据结构,能够有效将数据组织和管理在⼀起。按照我们的方式任意对数据进行增删改查等操作。最基础的数据结构:数组。

【思考】有了数组,为什么还要学习其他的数据结构?
假定数组有10个空间,已经使用了5个,向数组中插入数据步骤:
求数组的长度,求数组的有效数据个数,向下标为数据有效个数的位置插入数据(注意:这里是
否要判断数组是否满了,满了还能继续插⼊吗).....
假设数据量非常庞⼤,频繁的获取数组有效数据个数会影响程序执行效率。
结论:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。

顺序表 

一、顺序表的概念及结构 

1.1、线性表

线性表( linear list )是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中广泛使
用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,
线性表在物理上存储时,通常以数组和链式结构的形式存储。
案例:蔬菜分为绿叶类、⽠类、菌菇类。线性表指的是具有部分相同特性的⼀类数据结构的集合
如何理解逻辑结构和物理结构?

二、顺序表分类

顺序表和数组的区别
        ◦ 顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接⼝
顺序表分类
        ◦ 静态顺序表

概念:使用定长数组存储元素

静态顺序表缺陷:空间给少了不够用,给多了造成空间浪费

        ◦ 动态顺序表  

三、动态顺序表的实现

#define INIT_CAPACITY 4typedef int SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{SLDataType* a;int size; // 有效数据个数int capacity; // 空间容量
}SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);//扩容
void SLCheckCapacity(SL* ps);//头部插⼊删除 / 尾部插⼊删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);//指定位置之前插⼊/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);

 顺序表的应用

一、基于动态顺序表实现通讯录 

C语言基础要求:结构体、动态内存管理、顺序表、文件操作 

1、功能要求  

1)至少能够存储100个人的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系⼈信息
4)删除指定联系⼈
5)查找制定联系⼈
6)修改指定联系⼈
7)显示联系⼈信息

2、代码实现

【思考1】用静态顺序表和动态顺序表分别如何实现
【思考2】如何保证程序结束后,历史通讯录信息不会丢失
//SeqList.h#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h> 
#include"contact.h"//数据类型为PersonInfo
typedef struct PersonInfo SQDataType;
//typedef int SQDataType;//动态顺序表
typedef struct SeqList {SQDataType* a;int size;//保存有效数据个数int capacity;//空间的⼤⼩
}SLT;//初始化与销毁
void SeqListInit(SLT* psl);
void SeqListDesTroy(SLT* psl);
void SeqListPrint(SLT sl);
void CheckCapacity(SLT* psl);// 头部插⼊删除 / 尾部插⼊删除
void SeqListPushBack(SLT* psl, SQDataType x);
void SeqListPushFront(SLT* psl, SQDataType x);
void SeqListPopBack(SLT* psl);
void SeqListPopFront(SLT* psl);//查找
int SeqListFind(SLT* psl, SQDataType x);
// 在指定位置之前插⼊/删除
//void SeqListInsert(SLT* psl, int pos, SQDataType x);
void SeqListInsert(SLT* psl, size_t pos, SQDataType x);
void SeqListErase(SLT* psl, size_t pos);size_t SeqListSize(SLT* psl);
//修改指定位置的值
void SeqListAt(SLT* psl, size_t pos, SQDataType x);
//contact.h#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100
//前置声明
typedef struct SeqList contact;//⽤⼾数据
typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);
//contact.c#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
#include"SeqList.h"void LoadContact(contact* con) {FILE* pf = fopen("contact.txt", "rb");if (pf == NULL) {perror("fopen error!\n");return;}//循环读取⽂件数据PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){SeqListPushBack(con, info);}printf("历史数据导⼊通讯录成功!\n");
}void InitContact(contact* con) {SeqListInit(con);LoadContact(con);
}void AddContact(contact* con) {PeoInfo info;printf("请输⼊姓名:\n");scanf("%s", &info.name);printf("请输⼊性别:\n");scanf("%s", &info.sex);printf("请输⼊年龄:\n");scanf("%d", &info.age);printf("请输⼊联系电话:\n");scanf("%s", &info.tel);printf("请输⼊地址:\n");scanf("%s", &info.addr);SeqListPushBack(con, info);printf("插⼊成功!\n");
}int FindByName(contact* con, char name[]) {for (int i = 0; i < con->size; i++){if (0 == strcmp(con->a[i].name, name)) {return i;}}return -1;
}void DelContact(contact* con) {char name[NAME_MAX];printf("请输⼊要删除的⽤⼾姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("要删除的⽤⼾不存在,删除失败!\n");return;}SeqListErase(con, pos);printf("删除成功!\n");
}void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "联系电话",for (int i = 0; i < con->size; i++){printf("%-10s %-4s %-4d %15s %-20s\n",con->a[i].name,con->a[i].sex,con->a[i].age,con->a[i].tel,con->a[i].addr);}
}void FindContact(contact* con) {char name[NAME_MAX];printf("请输⼊要查找的⽤⼾姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("要查找的⽤⼾不存在,查找失败!\n");return;}printf("查找成功!\n");printf("%-10s %-4s %-4d %15s %-20s\n",con->a[pos].name,con->a[pos].sex,con->a[pos].age,con->a[pos].tel,con->a[pos].addr);
}void ModifyContact(contact* con) {char name[NAME_MAX];printf("请输⼊要修改的⽤⼾名称:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("要查找的⽤⼾不存在,修改失败!\n");return;}PeoInfo info;printf("请输⼊要修改的姓名:\n");scanf("%s", &con->a[pos].name);printf("请输⼊要修改的性别:\n");scanf("%s", &con->a[pos].sex);printf("请输⼊要修改的年龄:\n");scanf("%d", &con->a[pos].age);printf("请输⼊要修改的联系电话:\n");scanf("%s", &con->a[pos].tel);printf("请输⼊要修改的地址:\n");scanf("%s", &con->a[pos].addr);printf("修改成功!\n");
}void SaveContact(contact* con) {FILE* pf = fopen("contact.txt", "wb");if (pf == NULL) {perror("fopen error!\n");return;}//将通讯录数据写⼊⽂件for (int i = 0; i < con->size; i++){fwrite(con->a + i, sizeof(PeoInfo), 1, pf);}printf("通讯录数据保存成功!\n");
}void DestroyContact(contact* con) {SaveContact(con);SeqListDesTroy(con);
}
//test.c#include"SeqList.h"
#include"contact.h"void menu() {//通讯录初始化contact con;InitContact(&con);int op = -1;do {printf("********************************\n");printf("*****1、添加⽤⼾ 2、删除⽤⼾*****\n");printf("*****3、查找⽤⼾ 4、修改⽤⼾*****\n");printf("*****5、展⽰⽤⼾ 0、退出 *****\n");printf("********************************\n");printf("请选择您的操作:\n");scanf("%d", &op);switch (op){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:FindContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;default:printf("输⼊有误,请重新输⼊\n");break;}} while (op != 0);//销毁通讯录DestroyContact(&con);
}

二、顺序表经典算法 

经典算法OJ题1: 移除元素
经典算法OJ题2: 合并两个有序数组

三、顺序表的问题及思考 

1. 中间/头部的插⼊删除,时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容⼀般是呈2倍的增长,势必会有⼀定的空间浪费。例如当前容量为100,满了以后增容到
200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
思考:如何解决以上问题呢?

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

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

相关文章

【分布式事务 XA模式】MySQL XA模式详解

MYSQL中的XA事务 写在前面1. XA事务的基本原理2. MySQL XA事务操作 写在前面 MySQL 的 5.0.3 版本开始支持XA分布式事务&#xff0c;并且只有innoDB存储引擎支持XA事务。 1. XA事务的基本原理 XA事务本质上是一种基于两阶段提交的分布式事务&#xff0c;分布式事务可以理解成…

[LWC] Components Communication

目录 Overview ​Summary Sample Code 1. Parent -> Child - Public Setter / Property / Function a. Public Property b. Public getters and setters c. Public Methods 2. Child -> Parent - Custom Event 3. Unrelated Components - LMS (Lightning Message…

拍立淘助力电商新趋势:以图搜图购物成主流

拍立淘&#xff08;或称为“以图搜图”&#xff09;是一种基于图像识别的购物搜索技术&#xff0c;它允许用户通过上传图片或拍摄照片来搜索相似的商品。这一功能为电商领域带来了新的购物体验&#xff0c;使得搜索更加直观和便捷。 为了实现这样的功能&#xff0c;需要后端支…

【CSS-语法】

CSS-语法 ■ CSS简介■ CSS 实例■ CSS id 和 class选择器■ CSS 样式表■ 外部样式表(External style sheet)■ 内部样式表(Internal style sheet)■ 内联样式(Inline style)■ 多重样式 ■ CSS 文本■ CSS 文本颜色■ CSS 文本的对齐方式■ CSS 文本修饰■ CSS 文本转换■ CS…

网络原理 HTTP _ HTTPS

回顾 我们前面介绍了HTTP协议的请求和响应的基本结构 请求报文是由首行请求头空行正文来组成的 响应报文是由首行形影头空行响应正文组成的 我们也介绍了一定的请求头之中的键值对的属性 Host,Content-type,Content-length,User-agent,Referer,Cookie HTTP协议中的状态码 我们先…

网络原理TCP之“三次握手“

TCP内核中的建立连接 众所周知,TCP是有连接的. 当我们在客户端敲出socket new Socket(serverIp,severPort)时,就在系统内核就在建立连接 真正建立连接是在系统内核中建立的,我们程序员只是调用相关的api. 在此处,我们把TCP的建立连接称为三次握手. 系统在内核建立连接时如上…

【C/C++语法基础】5.C++的函数和数组(新手推荐)

前言 C是一种广泛使用的编程语言&#xff0c;具有强大的功能和灵活性。在C中&#xff0c;函数和数组是两个重要的概念&#xff0c;它们在程序设计中起着关键的作用。本文将介绍C中的函数和数组&#xff0c;并展示如何使用它们来完成各种任务。 函数 函数是C中的一种基本构造…

事务的特性 ACID

事务在数据库系统中是一个重要的概念&#xff0c;它确保了数据库操作的完整性和一致性。以下是每个特性的具体含义&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务必须被视为一个不可分割的最小工作单元&#xff0c;这意味着事务中的操作要么全部完成&…

SQL-FEFT JOIN (拼接表)

语法 SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_nametable2.column_name; 按照一定规则&#xff0c;将表table1和表table2拼接起来。 例&#xff1a; Employees 表&#xff1a; ------------------------ | Column Name | Type | ------…

QoS 服务质量

服务质量 QoS (Quality of Service) 服务质量可用若干基本性能指标来描述&#xff0c;包括&#xff1a;可用性、差错率、响应时间、吞吐量、分组丢失率、连接建立时间、故障检测和改正时间等。 服务提供者可向其用户保证某一种等级的服务质量。 服务性能的总效果&#xff0c;…

iOS高级理论:多线程专题 - (2) GCD信号量的应

一、控制最大并发数 对计算机了解的都会知道信号量的作用&#xff0c;当我们多个线程要访问同一个资源的时候&#xff0c;往往会设置一个信号量&#xff0c;当信号量大于0的时候&#xff0c;新的线程可以去操作这个资源&#xff0c;操作时信号量-1&#xff0c;操作完后信号量1…

第2.6章 StarRocks表设计——数据压缩

注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的数据压缩机制 1.数据压缩概述 StarRocks支持对表&#xff0c;索引数据进行压缩(compression)。数据压缩不仅有助于节省存储空间&#xff0c;还能提高I/O密集型任务的性能&#xff0c;但是压缩和解压数据需要额外的cpu资源。…

【接口加密】接口加密的未来发展与应用场景

目录 3.1 接口加密与区块链技术的结合 3.1.1 区块链技术的安全特性与优势 3.1.2 接口加密在区块链中的应用案例 3.2 接口加密与物联网安全 3.2.1 物联网安全的挑战与需求 3.2.2 接口加密在物联网领域的实际应用 3.3 接口加密在金融与电子商务领域的应用 随着信息技术的不…

【Java网络编程06】HTTPS原理

1. HTTPS基本概念 HTTPS&#xff1a;HTTPS也是一个应用层协议&#xff0c;它在HTTP协议的基础上引入了一个加密层——SSL协议&#xff0c;区别就在于HTTP协议是基于明文传输的&#xff08;不安全&#xff09;&#xff0c;使用HTTPS加密就能在一定程度上防止数据在传输过程中被…

redis架构系列——生产常用的部署模式介绍

主从高可用模式 这是最基本的高可用模式&#xff0c;它允许数据从主节点自动复制到一个或多个从节点。这种模式下&#xff0c;从节点可以处理读操作&#xff0c;从而实现负载均衡&#xff0c;并提供故障恢复的基本功能。然而&#xff0c;它的故障恢复不能自动化&#xff0c;写操…

内核解读之内存管理(8)什么是page cache

文章目录 0. 文件系统的层次结构1.什么是page cache2.感观认识page cache3. Page Cache的优缺点3.1 Page Cache 的优势3.2 Page Cache 的劣势 0. 文件系统的层次结构 在了解page cache之前&#xff0c;我们先看下文件系统的层次结构。 1 VFS 层 VFS &#xff08; Virtual Fi…

Vulhub 靶场训练 DC-8解析

一、环境搭建 kali的IP地址&#xff1a;192.168.200.14 DC-8的IP地址&#xff1a;192.168.200.13&#xff08;一个flag&#xff09; 靶机和攻击机处于同一个网络方式&#xff1a;nat或桥接 若出现开机错误&#xff0c;适当将dc的兼容版本改低&#xff0c;我的vmware workst…

pythonJax小记(三):python: 使用Jax已知若干坐标,提取二维矩阵中对应坐标的值(持续更新,评论区可以补充)

python: 使用Jax已知若干坐标&#xff0c;提取二维矩阵中对应坐标的值 前言直接上代码 前言 自用&#xff0c;刚开始接触可能顺序会比较乱。 直接上代码 import jax.numpy as jnp from jax import jitjit def _extractValues(matrix, positions): values matrix[pos…

Vue事件处理之v-on

1. 使用及定义 定义方法 function 方法名称(接受的event或是什么都不写) {//不管方法后括号内写与不写event,都可以接受到方法内表达式 }//定义一个接受参数的方法,此时也会在传入event function 方法名称(传入参数) {//可接受传入参数与event方法内表达式 } //定义一个接受参…

说一下 JVM 有哪些垃圾回收器?

如果说垃圾收集算法是内存回收的方法论&#xff0c;那么垃圾收集器就是内存回收的具体实现。下图展示了7种作用于不同分代的收集器&#xff0c;其中用于回收新生代的收集器包括Serial、ParNew、Parallel Scavenge&#xff0c;回收老年代的收集器包括SerialOld、Parallel Old、C…