C语言实现基础数据结构——顺序表

目录

顺序表

顺序表和数组

顺序表的分类

静态顺序表

动态顺序表

静态顺序表和动态顺序表的比较

动态顺序表的实现

主要实现功能

顺序表的初始化

顺序表的销毁

顺序表的打印

顺序表的尾部插入

顺序表的头部插入

顺序表的尾部删除

顺序表的头部删除

顺序表的指定位置插入

顺序表的指定位置删除

顺序表中的数值查找

顺序表应用——通讯录

主要实现的功能

初始化通讯录

添加通讯录数据

展示通讯录数据

删除通讯录数据

查找通讯录数据

修改通讯录数据

销毁通讯录数据


顺序表

顺序表和数组

顺序表的底层结构是数组,对数组的封装,实现了常用的增删改查等接口

📌

顺序表在逻辑结构上连续,并且在物理结构上也是连续

顺序表的分类

静态顺序表

数组的大小固定的顺序表

//静态顺序表
typedef int SLDataType;
#define N 7
typedef struct SeqList_static
{SLDataType SeqList[N];//数组长度为7的顺序表int size;//有效数值的个数,此处有效数值相当于数组的下标,并且总是指向最后一个有效数值的下一位
};

动态顺序表

数组大小可以指定改变的顺序表

typedef int SLDataType;
typedef struct SeqList_dynamic
{SLDataType* SeqList;//指向可以修改大小的数据空间int size;//有效数据个数int capacity;//数据空间的总大小
};

静态顺序表和动态顺序表的比较

静态顺序表空间给少了不够用,给多了造成空间浪费,实际使用顺序表更多使用动态顺序表

动态顺序表的实现

主要实现功能

//初始化和销毁 
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);

顺序表的初始化

//顺序表的初始化
void SLInit(SL_d* ps)
{assert(ps);//确保没有传入空指针ps->SeqList = NULL;ps->size = 0;
}

顺序表的销毁

//顺序表的销毁
void SLDestroy(SL_d* ps)
{assert(ps);if (ps->SeqList == NULL){free(ps->SeqList);}ps->SeqList = NULL;ps->size = 0;ps->capacity = 0;
}

顺序表的打印

//顺序表的打印
void SLPrint(SL_d* ps)
{assert(ps);assert(ps->SeqList);for (int i = 0; i < ps->size; i++){printf("%d ", ps->SeqList[i]);}putchar('\n');
}

顺序表的尾部插入

基本思路:判断是否需要扩容再进行尾部插入

    1. 当顺序表有足够的空间插入时(包括有内容和顺序表为空):直接在顺序表尾部插入
    2. 当顺序表空间已满时:扩容后再插入

//顺序表的扩容 
void SLCheckCapacity(SL_d* ps)
{assert(ps);SLDataType* temp = NULL;if (ps->size == ps->capacity){int newCapacity = ps->capacity;temp = (SLDataType*)realloc(ps->SeqList, (newCapacity =  (ps->capacity == 0) ? 4 : (ps->capacity * 2)) * sizeof(SLDataType));//扩容规则:成倍数增加(一般1.5倍或2倍)assert(temp);ps->SeqList = temp;ps->capacity = newCapacity;temp = NULL;}
}//顺序表的尾部插入
//当顺序表有足够的空间插入时(包括有内容和顺序表为空)
void SLPushBack(SL_d* ps, SLDataType x)
{assert(ps);//顺序表的扩容 SLCheckCapacity(ps);//确保SeqList指针不为空之后判断容量是否足够//当顺序表有足够的空间插入时(包括有内容和顺序表为空)ps->SeqList[ps->size] = x;ps->size++;//当顺序表空间已满时//先进行扩容操作//再进行插入
}

顺序表的头部插入

基本思路:判断容量是否足够再进行头部插入

    1. 当顺序表有足够的空间插入时(包括有内容和顺序表为空):直接在顺序表尾部插入
    2. 当顺序表空间已满时:扩容后再插入
//顺序表的扩容 
void SLCheckCapacity(SL_d* ps)
{assert(ps);SLDataType* temp = NULL;if (ps->size == ps->capacity){int newCapacity = ps->capacity;temp = (SLDataType*)realloc(ps->SeqList, (newCapacity =  (ps->capacity == 0) ? (ps->capacity) : (ps->capacity * 2)) * sizeof(SLDataType));//扩容规则:成倍数增加(一般1.5倍或2倍)assert(temp);ps->SeqList = temp;ps->capacity = newCapacity;temp = NULL;}
}//顺序表的头部插入
void SLPushFront(SL_d* ps, SLDataType x)
{assert(ps);//顺序表的扩容SLCheckCapacity(ps);//确保SeqList指针不为空之后判断容量是否足够//顺序表有足够的空间插入时(包括有内容和顺序表为空)for (int i = ps->size - 1; i >= 0; i--){ps->SeqList[i + 1] = ps->SeqList[i];//ps->SeqList[0] = ps->SeqList[1]}ps->SeqList[0] = x;ps->size++;//当顺序表空间已满时//先进行扩容操作//再进行插入
}

顺序表的尾部删除

基本思路:将有效数值变量前移达到“看不见即删除”的效果

//顺序表的尾部删除
void SLPopBack(SL_d* ps)
{assert(ps);assert(ps->size);//确保顺序表内不为空ps->size--;
}

顺序表的头部删除

基本思路:将后面的值一一往前覆盖,并且有效数值变量前移

//顺序表的头部删除
void SLPopFront(SL_d* ps)
{assert(ps);assert(ps->size);for (int i = 0; i < ps->size; i++){ps->SeqList[i] = ps->SeqList[i + 1];}ps->size--;
}

顺序表的指定位置插入

基本思路:以插入位置(第一个数值位置为1)为标准,将插入位置后面的内容向后移动,并且有效数值变量后移

//顺序表的指定位置插入
void SLInsert(SL_d* ps, int pos, SLDataType x)
{assert(ps);for (int i = ps->size - 1; i >= pos - 1; i--){ps->SeqList[i + 1] = ps->SeqList[i];}ps->SeqList[pos - 1] = x;ps->size++;
}

顺序表的指定位置删除

基本思路:以删除位置(第一个数值位置为1)为标准,将删除位置之后的数值覆盖删除位置的数值,并且有效数值前移

//顺序表的指定位置删除
void SLErase(SL_d* ps, int pos)
{assert(ps);for (int i = pos; i < ps->size ; i++){ps->SeqList[i - 1] = ps->SeqList[i];}ps->size--;
}

顺序表中的数值查找

基本思路:遍历顺序表查找

//使用遍历顺序表在顺序表中找指定数值
int SLFind(SL_d* ps, SLDataType x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->SeqList[i] == x){return i + 1;}}return 0;
}

顺序表应用——通讯录

主要实现的功能

  1. 至少能够存储100个⼈的通讯信息
  2. 能够保存用户信息:名字、性别、年龄、电话、地址等
  3. 增加联系⼈信息
  4. 删除指定联系⼈
  5. 查找制定联系⼈
  6. 修改指定联系⼈
  7. 显示联系⼈信息
//初始化通讯录 
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);

初始化通讯录

//初始化通讯录
void InitContact(contact* con)
{SLInit(&con);
}

添加通讯录数据

//添加联系人
void AddContact(contact* con)
{info c = { 0 };printf("请输入联系人姓名:");scanf("%s", c.name);printf("请输入联系人年龄:");scanf("%d", &(c.age));printf("请输入联系人性别:");scanf("%s", c.gender);printf("请输入联系人电话:");scanf("%s", c.phoneNum);printf("请输入联系人住址:");scanf("%s", c.address);assert(con);SLPushBack(con, c);
}

展示通讯录数据

//显示联系人
void ShowContact(contact* con)
{assert(con);printf("姓名\t年龄\t性别\t\t电话\t住址\n");for (int i = 0; i < con->size; i++){printf("%s\t%d\t%s\t\t%s\t%s\t\n", con->SeqList[i].name, con->SeqList[i].age, con->SeqList[i].gender, con->SeqList[i].phoneNum, con->SeqList[i].address);}
}

删除通讯录数据

//查找联系人,以按名字查找为例
int FindContact(contact* con, char *name)
{assert(con);assert(con->SeqList);for (int i = 0; i < con->size; i++){if (strcmp(con->SeqList[i].name, name) == 0){printf("姓名\t年龄\t性别\t\t电话\t住址\n");printf("%s\t%d\t%s\t\t%s\t%s\t\n",con->SeqList[i].name, con->SeqList[i].age,con->SeqList[i].gender, con->SeqList[i].phoneNum,con->SeqList[i].address);return i + 1;}else{continue;}if(i == con->size - 1){ printf("查找无此人");return 0;}}
}//删除联系人
void DelContact(contact* con, char *name)
{assert(con);assert(con->SeqList);//删除联系人首先得有需要删除的联系人,以按名字查找为例if (FindContact(con, name)){SLErase(con, FindContact(con, name));}
}

查找通讯录数据

//查找联系人,以按名字查找为例
int FindContact(contact* con, char *name)
{assert(con);assert(con->SeqList);for (int i = 0; i < con->size; i++){if (strcmp(con->SeqList[i].name, name) == 0){printf("查找到的联系人如下:\n");printf("姓名\t年龄\t性别\t\t电话\t住址\n");printf("%s\t%d\t%s\t\t%s\t%s\t\n",con->SeqList[i].name, con->SeqList[i].age,con->SeqList[i].gender, con->SeqList[i].phoneNum,con->SeqList[i].address);return i + 1;}}printf("查找无此人\n");return 0;
}

修改通讯录数据

//修改联系人
void ModifyContact(contact* con, char* name)
{assert(con);assert(con->SeqList);//修改联系人前提得有需要修改的联系人int ret = FindContact(con, name) - 1;//函数返回的不是下标,而是当前内容所在的位置,从1开始计数if (ret){printf("请输入需要修改的联系人姓名:");scanf("%s", con->SeqList[ret].name);printf("请输入需要修改的联系人年龄:");scanf("%d", &(con->SeqList[ret].age));printf("请输入需要修改的联系人性别:");scanf("%s", con->SeqList[ret].gender);printf("请输入需要修改的联系人电话:");scanf("%s", con->SeqList[ret].phoneNum);printf("请输入需要修改的联系人住址:");scanf("%s", con->SeqList[ret].address);    }
}

销毁通讯录数据

//销毁通讯录
void DestroyContact(contact* con)
{SLDestroy(con);
}

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

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

相关文章

如何使用docker compose安装APITable并远程访问登录界面

文章目录 前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 …

Java基础常见面试题总结(下)

常见的Exception有哪些&#xff1f; 常见的RuntimeException&#xff1a; ClassCastException //类型转换异常IndexOutOfBoundsException //数组越界异常NullPointerException //空指针ArrayStoreException //数组存储异常NumberFormatException //数字格式化异常ArithmeticE…

Mysql-InnoDB-数据落盘

概念 1 什么是脏页&#xff1f; 对于数据库中页的修改操作&#xff0c;则首先修改在缓冲区中的页&#xff0c;缓冲区中的页与磁盘中的页数据不一致&#xff0c;所以称缓冲区中的页为脏页。 2 脏页什么时候写入磁盘&#xff1f; 脏页以一定的频率将脏页刷新到磁盘上。页从缓冲区…

教你一招,测试人员如何通过AI提高工作效率!

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

C++仿函数、万能头文件、transform学习

这是网上的一个代码,里面的一些东西以前没用过; #include <bits/stdc++.h> using namespace std;// A Functor class increment { private:int num; public:increment(int n) : num(n) { }int operator () (int arr_num) const {return num + arr_num;} };// Driver …

【破事水】Java Gradle 无法引入同名不同版本的两个包

此问题水于 2024 年 01 月&#xff0c;假如后面 gradle 出了什么好方法能解决这个问题&#xff0c;家祭无忘告乃翁&#xff0c;提前谢过看到这篇的各位大佬了。 结论 先说结论&#xff0c;Java 因为包名定义等原因&#xff0c;对同名包在编译时只能编译一个版本&#xff0c;具…

Kafka高级_生产者ACk机制数据一致性问题

Kafka高级_生产者ACk机制&数据一致性问题 目录需求&#xff1a; 设计思路实现思路分析1.Kafka高级_生产者ACk机制2.Kafka高级数据一致性问题 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c…

微信小程序开发学习笔记《13》WXS脚本

微信小程序开发学习笔记《13》WXS脚本 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读对应官方文档 一、WXS介绍 WXS ( WeiXin Script)是小程序独有的一套脚本语言&#xff0c;结合WXML&#xff0c;可以构建出页面的…

CSDN COC·北京开发者社区2023年度聚会

CSDN COC北京开发者社区2023年度聚会 年末盛会&#xff1a;北京开发者社区2023年度聚会 1. 活动背景&#x1f389;2. 活动议程3. 活动亮点介绍 &#x1f31f;3.1 主理人开场破冰3.2 话题讨论&#xff1a;3.3 城市社区介绍、回顾与展望 &#x1f3d9;️4. 活动留念5.活动总结 博…

浅出深入-机器学习

文章目录 一、K近邻算法1.1 先画一个散列图1.2 使用K最近算法建模拟合数据1.3 进行预测1.4 K最近邻算法处理多元分类问题1.5 K最近邻算法用于回归分析1.6 K最近邻算法项目实战-酒的分类1.6.1 对数据进行分析1.6.2 生成训练数据集和测试数据集1.6.3 使用K最近邻算法对数据进行建…

计算机网络——路由信息协议 (RIP) 实验

1.实验题目 实验五&#xff1a;路由信息协议 (RIP) 实验 2.实验目的 &#xff08;1&#xff09;了解RIP的相关知识以及原理。 &#xff08;2&#xff09;掌握RIP路由的配置方法。 3.实验任务 (1) 路由器的基本配置&#xff1a;设置路由器接口 IP 地址。 (2) 根据以上拓扑…

Python Tornado 实现SSE服务端主动推送方案

一、SSE 服务端消息推送 SSE 是 Server-Sent Events 的简称&#xff0c; 是一种服务器端到客户端(浏览器)的单项消息推送。对应的浏览器端实现 Event Source 接口被制定为HTML5 的一部分。相比于 WebSocket&#xff0c;服务器端和客户端工作量都要小很多、简单很多&#xff0c…

[m1pro ] ssh: connect to host localhost port 22: Connection refused

在学习Hadoop 的时候&#xff0c;使用 ssh localhost 遇到以下问题 原因&#xff1a; 本地没有打开远程登录 解决办法&#xff1a;打开远程登录 成功结果

防御保护---防火墙的用户认证

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.用户认证概述 防火墙用户认证是一种安全措施&#xff0c;用于验证和授权网络用户的身份。它是防火墙的一部分&#xff0c;旨在确保只有经过身份验证的用户才能访问网络资源。 防火墙用户认证…

JDK1.8新特性(Day24)

Lambda表达式 介绍 Lambda表达式是一种没有名字的函数,也可称为闭包&#xff0c;是Java 8 发布的最重要新特性。本质上是一段匿名内部类&#xff0c;也可以是一段可以传递的代码。还有叫箭头函数的... 闭包 闭包就是能够读取其他函数内部变量的函数,比如在java中,方法内部的局…

智慧文旅:打造无缝旅游体验的关键

随着科技的快速发展和消费者需求的不断升级&#xff0c;旅游业正面临着前所未有的变革压力。智慧文旅作为数字化转型的重要领域&#xff0c;旨在通过智能化、数据化手段为游客提供更加优质、便捷、个性化的服务&#xff0c;打造无缝的旅游体验。本文将深入探讨智慧文旅在打造无…

第九节HarmonyOS 常用基础组件17-ScrollBar

1、描述 滚动条组件ScrollBar&#xff0c;用于配合可滚动组件使用&#xff0c;如List、Grid、Scroll。 2、接口 可包含子组件 ScrollBar(value:{scroller:Scroller, direction?: ScrollBarDirection, state?: BarState}) 3、参数 参数名 参数类型 必填 描述 scrolle…

R-YOLO

Abstract 提出了一个框架&#xff0c;名为R-YOLO&#xff0c;不需要在恶劣天气下进行注释。考虑到正常天气图像和不利天气图像之间的分布差距&#xff0c;我们的框架由图像翻译网络&#xff08;QTNet&#xff09;和特征校准网络&#xff08;FCNet&#xff09;组成&#xff0c;…

spire.doc合并word文档

文章目录 spire.doc合并word文档1. 引入maven依赖2. 需要合并的word3. 合并文档代码4. 合并结果5. 合并产生段落&#xff0c;table样式混乱问题 spire.doc合并word文档 1. 引入maven依赖 <repositories><repository><id>com.e-iceblue</id><name&g…

CH395Q之CH395Q简介(一)

本节主要介绍以下内容&#xff1a; 1、TCP/IP协议栈是什么&#xff08;了解&#xff09; 2、CH395Q是什么&#xff08;了解&#xff09; 3、CH395Q工作命令&#xff08;熟悉&#xff09; 4、CH395Q & W5500 一、TCP/IP协议栈是什么 是一系列网络协议的总和&#xff0…