【数据结构(顺序表)】

news/2025/2/12 9:00:57/

一、什么是数据结构?

数据结构是由“数据”和“结构”两词组合而来。
什么是数据?常见的数值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.ppmy.cn/news/1361037.html

相关文章

IO线程进程作业day6

1> 将标准io文件IO的内容复习一遍 2> 进程线程的相关函数复习一遍 3> 将信号和消息队列的课堂代码敲一遍 1、处理普通信号 #include <myhead.h> //定义信号处理函数 void handler(int signo) {if(signoSIGINT){puts("按下ctrlc");} } int main(in…

二次元风格个人主页HTML源码

源码介绍 直接上传服务器压缩包解压就完事了&#xff0c;修改index.html内代码即可&#xff0c;注释写的很全&#xff0c;替换图片在文件夹img&#xff0c;只有前端&#xff0c;没有后台&#xff0c;大佬如果需要&#xff0c;可以自行添加后台。本源码非常适合个人工作室主页。…

【新手易错点】golang中byte和rune

1 总体区别 在Golang中&#xff0c;byte和rune是两种不同类型的数据。简单来说&#xff0c;byte是一个8位的无符号整数类型&#xff0c;而rune则是一个32位的Unicode字符类型。 Byte: 在Golang中&#xff0c;byte类型实际上是uint8的别名&#xff0c;它用来表示8位的无符号整…

Uniapp小程序开发-底部tabbar的开发思路

文章目录 前言一、uniapp 实现 tabbar二、图标使用网络图片后端返回tabbar信息uniapp方式中的setTabBarItem 总结 前言 记录uniapp 开发小程序的底部tabbar &#xff0c;这里讨论的不是自定义tabbar的情况。而是使用wx.setTabBarItem(Object object) 这个api的情况。关于custo…

神经网络系列---回归问题和分类问题

文章目录 回归问题和分类问题回归问题&#xff1a;分类问题&#xff1a;多分类问题&#xff1a;排序问题&#xff1a;自定义损失函数&#xff1a; 回归问题和分类问题 回归问题&#xff1a; 回归问题是一种预测连续数值输出的任务。在这种问题中&#xff0c;模型的目标是根据…

OpenCV 4基础篇| OpenCV像素的编辑

目录 1. 前言1. 像素的访问1.1 数组索引访问1.2 img.item() 2. 像素的修改2.1 数值索引修改2.2 img.itemset() 1. 前言 像素是构成数字图像的基本单位&#xff0c;像素处理是图像处理的基本操作。 对像素的访问、修改&#xff0c;可以使用 Numpy 方法直接访问数组元素。 1. 像…

《TCP/IP详解 卷一》第3章 链路层

目录 3.1 引言 3.2 以太网 3.3 全双工 省点 自动协商 流量控制 3.4 网桥和交换机 3.5 WiFi 3.6 PPP协议 3.6.1 PPP协议流程 3.7 环回 3.8 MTU和路径MTU 3.9 隧道基础 3.9.1 GRE 3.9.2 PPTP 3.9.3 L2TP 3.10 与链路层相关的攻击 3.11 总结 3.1 引言 城域网&…

fly-barrage 前端弹幕库(1):项目介绍

fly-barrage 是我写的一个前端弹幕库&#xff0c;由于经常在 Bilibili 上看视频&#xff0c;所以对网页的弹幕功能一直蛮感兴趣的&#xff0c;所以做了这个库&#xff0c;可以帮助前端快速的实现弹幕功能。 项目官网地址&#xff1a;https://fly-barrage.netlify.app/&#xff…