《数据结构》--顺序表
C语言语法基础到数据结构与算法,前面已经掌握并具备了扎实的C语言基础,为什么要学习数据结构课程?--我们学完本章就可以实践一个:通讯录项目
简单了解过后,通讯录具备增加、删除、修改、查找联系人等操作。要想实现通讯录项目必须有两个技术关键:(1)C语言语法基础(2)数据结构 之 顺序表/链表。
一、初步了解数据结构
什么是数据结构?数据结构就是“数据”与“结构”两个词组合而来。
什么是数据:常见的数值1、2、3......、教务系统里保存的用户信息(姓名、性别、年龄、学历等)、网页里的图片、视频、文字等等,都是数据。(我们知晓的所有信息都可以称之为数据,数据在计算机中存储的方式都是二进制数字,包括图文、视频等)
什么是结构:当我们想要大量使用同一类型的数据时,通过手动定义大量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将大量的数据组织在一起,结构也可以理解为组织数据的方式。
概念:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在的一种或多种特定关系的数据元素的集合。数据结构反映数据的内部构成,即数据由哪部分构成、以什么方式构成、以及数据元素之间呈现的结构。
小结:
1.能够存储数据(如顺序表、链表等结构)
2.存储的数据能够方便查找
为什么需要数据结构?通过数据结构可以有效的将数据组织和管理在一起。按照我们的方式任意对数据进行增删查改等操作。最基础的数据结构:数组。
【思考】有了数组,为什么还要学习其它数据结构?
假定数组有10个空间,已经使用了5个,向数组中插入数据的步骤有:
1.求数组的长度(求总长是为了判断有效个数与最大长度是否相等,数组满员还能继续插入吗?) 2.求数组的有效数据个数 3.向下标为数据有效个数的位置插入数据
假设数据量非常的庞大,频繁的获取数组有效个数会影响程序执行效率。
结论:最基础的数据结构能提供的操作已经不能完全满足复杂算法的实现。
二、顺序表
1.顺序表的概念及结构
顺序表是一种线性表。线性表(linear list)是n个相同特性的数据元素的有限序列。线性表是一种在实际中广泛应用的数据结构,常见的线性表包括:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上的存储方式通常是顺序(数组)存储和链式存储。
如何理解逻辑结构和物理结构?下面给大家画一张图:
第一种就是物理顺序和逻辑顺序一致,在一段连续的空间中依次存放数据。第二种就是这些数据逻辑上是一条线,但由于存储的位置不连续,在忽略其它空间的情况下,将这些空间取出并将其放置到一条直线上就可以验证它的线性存储形式是逻辑线性,物理上的存储是不确定的。
2.顺序表分类
顺序表和数组的区别:顺序表的底层结构是数组,对数组的封装,实现了常用的增删查改等接口。
分类:静态顺序表-动态顺序表
//静态顺序表
typedef int DataType;
#define SQLIST_INIT_LENGTH 10
typedef struct SqList{DataType arr[SQLIST_INIT_LENGTH];size_t _size;//有效数据个数,每插入一个数据就会+1,用来记录
}SL;
//静态顺序表缺陷:空间给少了不够用,给多了造成空间浪费
//动态顺序表--按需分配
typedef struct SqList{DataType* arr;size_t _size;//有效数据个数size_t _capacity;//空间容量
}SL;
3.动态顺序表的基本操作
#define LIST_INIT_SIZE 10
typedef int DataType;
typedef struct SqList{DataType* arr;size_t size;//有效数据个数size_t capacity;//空间容量
}SL;//判空、取长、寻值
bool isEmpty(SL s);
int GetSize(SL s);
int SLFind(SL s,DataType data);//初始化与销毁
void SLInit(SL* s);
void SLDestroy(SL* s);
//打印
void SLPrint(SL s);
//扩容
void SLCheckCapacity(SL* s);
//修改指定位置的值
void UpdateNode(SL* s,int index,DataType data);//指定位置之前插入/删除数据
void SLInsert(SL* s,int index,DataType data);
void DeleteByIndex(SL* s,int index);
//按值删除数据
void DeleteByData(SL& s,DataType data);//增删操作也可以有下面的几种
//头插、头删、尾插、尾删
void SLInsert_Head(SL* s,DataType data);
void SLDelete_Head(SL* s);
void SLInsert_Tail(SL* s,DataType data);
void SLDelete_Tail(SL* s);
三、动态顺序表的实现
1.顺序表的判空操作
顺序表的内容是否为空主要就是看里面的动态数组是否指向空指针。然后返回这个表达式的结果(布尔类型)。
bool isEmpty(SL s)
{return (s.arr == nullptr);
}
2.顺序表的长度
我们说的顺序表的长度是有效数据个数而非顺序表的空间总量 。所以我们返回的就是顺序表内部的size属性。
int GetSize(SL s)
{return s.size;
}
3.查找某值在顺序表的位置
查找某值在顺序表的位置时,首先判断顺序表是不是空的,如果是空的,那就没必要再继续了,直接返回-1。否则,循环遍历直至顺序表中顺组的有效长度的最后一个值。如果循环结束仍未找到,返回-1。那么综上返回-1就代表表内无该元素。
int SLFind(SL s, DataType data)
{if (isEmpty(s))return -1;else{for (int i = 0; i < s->size; i++) {if (*(s->arr + i) == data) {return i;}}}return -1;
}
4.顺序表的初始化与销毁
初始化时使用宏定义的初始化长度LIST_INIT_SIZE,使用malloc为数组申请一定长度的空间,然后对该表进行判断,如果仍然为空说明malloc申请空间时由于某些原因申请失败了,离开程序。否则就将顺序表的最大长度设为初始值,有效长度设为0。
销毁顺序表时,将顺序表长度和空间容量都置零,令数组指针指向NULL(按理来说nullptr更为严谨)。最后使用free释放内存空间。
//初始化顺序表:给arr开辟10个空间void SLInit(SL* s){s->arr = (DataType*)malloc(sizeof(DataType) * LIST_INIT_SIZE);if (isEmpty(*s))exit(OVERFLOW);//s->arr = new DataType[LIST_INIT_SIZE];s->capacity = LIST_INIT_SIZE;s->size = 0;//尚未存储数据}//销毁顺序表void SLDestroy(SL* s){assert(s->arr);//在头文件<assert.h>中s->capacity = s->size = 0;s->arr = NULL;free(s->arr);cout << "销毁完毕" << endl;}
5.顺序表打印
如果顺序表为空,那还打印什么,直接告诉用户顺序表为空就可以了。非空的话,那就循环遍历顺序表的有效数据,将其中存储的值依次打印出来。
void PrintSqlist(SL s)
{if (isEmpty(s))cout << "顺序表为空";else {for (int i = 0; i < s.size; i++)cout << *(s.arr + i) << " ";}cout << endl;
}
6.顺序表插入数据
此处涉及到一个扩容的问题:当有效长度与最大容量相等时,说明顺序表满了,需要使用realloc动态扩容,考虑到不断扩容会导致效率变低或者出现问题,我们每次表满时直接选择二倍扩容。
//尾插
void SLInsert_Tail(SL* s, DataType data)
{if (isEmpty(*s)) {SLInit(s);//如果顺序表为空,则开辟一个顺序表}if ((s->size) == (s->capacity)){//2倍扩容DataType* tmp = (DataType*)realloc(s->arr, (s->capacity * 2) * sizeof(DataType));assert(tmp);//判断指针是否为空s->arr = tmp;//(s->capacity) *= 2;}*(s->arr + s->size) = data;(s->size)++;
}//指定位置插入
void SLInsert(SL* s, int index, DataType data)
{if (isEmpty(*s)) SLInit(s);if (index < 0 || index > s->size) return;if (s->size == s->capacity){int newcapacity = s->capacity * 2;DataType* tmp = (DataType*)realloc(s->arr, sizeof(DataType) * newcapacity);assert(tmp);s->arr = tmp;}for (int i = s->size; i >= index; i--){s->arr[i + 1] = s->arr[i];}s->arr[index] = data;s->size++;
}
7.顺序表删除数据
//删除顺序表第index位数据(按位删)
void DeleteByIndex(SL* s, int index)
{if (isEmpty(*s)|| index > s->size||index < 0)cout << "空表或索引溢出" << endl;else {for (int i = index; i < (s->size); i++) {DataType tmp = *(s->arr + i);*(s->arr + i) = *(s->arr + i + 1);*(s->arr + i + 1) = tmp;}(s->size)--;}cout << "删除成功" << endl;
}//删除顺序表数据data(按值删)
void DeleteByData(SL& s, DataType data)
{if (isEmpty(s))cout << "空表" << endl;else {for (int i = 0; i < s.size; i++){if (*(s.arr + i) == data) {for (int j = i; j < s.size; j++){DataType tmp = *(s.arr + j);*(s.arr + j) = *(s.arr + j + 1);*(s.arr + j + 1) = tmp;}s.size--; }cout << "删除完毕" << endl;}}
}
8.修改顺序表内容
void UpdateNode(SL* s, int index, DataType data)
{if (isEmpty(*s))cout << "顺序表为空" << endl;else{*(s->arr + index) = data;cout << "修改成功" << endl;}
}
9.顺序表扩容
扩容操作参考插入时的特殊处理。
我们在下节的项目实战中完成顺序表实现通讯录。(大家先试着完成写一写自己的通讯录系统,独立的完成每一个小项目才能为完成大项目积累经验)。加油各位!
相关文章:

《数据结构》--顺序表
C语言语法基础到数据结构与算法,前面已经掌握并具备了扎实的C语言基础,为什么要学习数据结构课程?--我们学完本章就可以实践一个:通讯录项目 简单了解过后,通讯录具备增加、删除、修改、查找联系人等操作。要想实现通…...
Qt:愚蠢的qmake
博主参与了一个使用qmake构建的项目,包含几百个源文件,最近遇到一个恼人的问题:有时仅仅修改了一个.cpp文件,构建项目时就有可能触发全编译。但是编译时又会命中ccache的缓存,这说明源代码实际上内容并没有发生变化。即…...
Apache Dubbo:分布式服务框架的深度解析
文章目录 引言官网链接Dubbo 原理架构概览通信协议负载均衡 基础使用1. 引入依赖2. 配置服务提供者3. 配置服务消费者4. 配置注册中心 高级使用1. 集群容错2. 泛化引用3. 异步调用 优缺点优点缺点 结论 引言 Apache Dubbo 是一个高性能、轻量级的开源 Java RPC 框架。它提供了…...

【前端学习】CSS三大特性
CSS三大特性 CSS的三大特性是为了化简代码、定位问题并且解决问题 继承性 继承性特点: 子级默认继承父级的文字控制属性。注意:如果标签自己有样式则生效自己的样式,不继承。 <!DOCTYPE html> <html lang"en"><…...

了解网络是如何运作
“Web 的工作原理”提供了一个简化的视图,用于了解在计算机或手机上的 Web 浏览器中查看网页时发生的情况。 这个理论对于短期内编写 Web 代码来说并不是必需的,但不久之后,你就会真正开始从理解后台发生的事情中受益。 客户端和服务器 连接到 Internet 的计算机称为客户端和…...

传输层协议——TCP
TCP协议 TCP全称为“传输控制协议”,要对数据的传输进行一个详细的控制。 特点 面向连接的可靠性字节流 TCP的协议段格式 源/目的端口:表示数据从哪个进程来,到哪个进程4位首部长度:表示该TCP头部有多少字节(注意它…...

C++相关概念和易错语法(23)(set、仿函数的应用、pair、multiset)
1.set和map存在的意义 (1)set和map的底层都是二叉搜索树,可以达到快速排序(当我们按照迭代器的顺序来遍历set和map,其实是按照中序来遍历的,是排过序的)、去重、搜索的目的。 (2&a…...

netty入门-3 EventLoop和EventLoopGroup,简单的服务器实现
文章目录 EventLoop和EventLoopGroup服务器与客户端基本使用增加非NIO工人NioEventLoop 处理普通任务与定时任务 结语 EventLoop和EventLoopGroup 二者大概是什么这里不再赘述,前一篇已简述过。 不理解也没关系。 下面会简单使用,看了就能明白是什么 这…...

通信原理-思科实验五:家庭终端以太网接入Internet实验
实验五 家庭终端以太网接入Internet实验 一实验内容 二实验目的 三实验原理 四实验步骤 1.按照上图选择对应的设备,并连接起来 为路由器R0两个端口配置IP 为路由器R1端口配置IP 为路由器设备增加RIP,配置接入互联网的IP的动态路由项 5.为路由器R1配置静…...
【Vue】vue概述
1、简介 Vue.js(简称Vue)是一款用于构建用户界面的渐进式JavaScript框架。由前Google高级软件工程师尤雨溪(Evan You)于2014年创建,是一个独立且社区驱动的开源项目。Vue.js基于标准的HTML、CSS和JavaScriptÿ…...
Docker use experience
#docker command docker load -i <镜像文件.tar> docker run -it -d --name 容器名 -p 宿主机端口:容器端口 -v 宿主机文件存储位置:容器内文位置 镜像名:Tag /bin/bash docker commit -m"提交的描述信息" -a"作者" 容器ID 要…...

Android平台RTSP|RTMP直播播放器技术接入说明
技术背景 大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台…...

数据结构——栈(顺序结构)
一、栈的定义 栈是一种数据结构,它是一种只能在一端进行插入和删除操作的特殊线性表。这一端被称为栈顶,另一端被称为栈底。栈按照后进先出(LIFO)的原则进行操作(类似与手枪装弹后射出子弹的顺序)。在计算…...
速盾:cdn能防御ddos吗?
CDN(内容分发网络)是一种广泛应用于互联网中的技术,它通过将内容分发到全球各地的服务器上,以提高用户在访问网站时的加载速度和稳定性。然而,CDN是否能够有效防御DDoS(分布式拒绝服务)攻击是一…...

分享 2 个 .NET EF 6 只更新某些字段的方法
前言 EF 更新数据时,通常情况下,是更新全部字段的,但实际业务中,更新全部字段的情况其实很少,一般都是修改其中某些字段,所以为了实现这个目标,很多程序员通常会这样作: 先从数据库…...

vs code解决报错 (c/c++的配置环境 远端机器为Linux ubuntu)
参考链接:https://blog.csdn.net/fightfightfight/article/details/82857397 https://blog.csdn.net/m0_38055352/article/details/105375367 可以按照步骤确定那一步不对,如果一个可以就不用往下看了 目录 一、检查一下文件扩展名 二、安装扩展包并…...

08 字符串和字节串
使用单引号、双引号、三单引号、三双引号作为定界符(delimiter)来表示字符串,并且不同的定界符之间可以相互嵌套。 很多内置函数和标准库对象也都支持对字符串的操作。 x hello world y Python is a great language z Tom said, "Le…...
vue使用mavonEditor(流程图、时序图、甘特图实现)
mavonEditor 安装mavonEditor $ npm install mavon-editor --save使用 // 全局注册import Vue from vueimport mavonEditor from mavon-editorimport mavon-editor/dist/css/index.css// useVue.use(mavonEditor)new Vue({el: #main,data() {return { value: }}})//局部使用…...

Java实现短信验证码服务
1.首先这里使用的是阿里云的短信服务。 package com.wzy.util;; import cn.hutool.captcha.generator.RandomGenerator; import com.aliyun.dysmsapi20170525.Client; import com.wzy.entity.Ali; import org.springframework.stereotype.Component;/*** Author: 顾安* Descri…...
python中的线程
线程 线程概念 线程 在一个进程的内部, 要同时干多件事, 就需要同时运行多个"子任务", 我们把进程内的这些"子任务"叫做线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中, 是进程的实际运作单位。一条线程指的是进程中一个单一顺序的控制流…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...