day19-线性表(顺序表)(链表I)

一、补充

  • 安装软件命令: sudo apt-get install  (软件名)
  1. 安装格式化对齐:sudo apt-get install clang-format
  2. 内存泄漏检测工具: sudo apt-get install valgrind

        编译后,使用命令         valgrind ./a.out        即可看内存是否泄露

二、 顺序表的基本操作

        表头结构是可选项,但最好在使用中加上;

#ifndef _SEQLIST_H_
#define _SEQLIST_H_typedef struct person
{char name[32];char sex;int age;int score;
} DATATYPE;typedef struct list
{DATATYPE *head;int tlen;int clen;
} SeqList;
//创建顺序表
SeqList *CreateSeqList(int len);
//销毁顺序表
int DestroySeqList(SeqList *list);
//遍历顺序表
int ShowSeqList(SeqList *list);
//尾插,在顺序表最后插入元素
int InsertTailSeqList(SeqList *list, DATATYPE *data);
//判断表是否满
int IsFullSeqList(SeqList *list);
//判断表是否为空表
int IsEmptySeqList(SeqList *list);
//按指定位置插入元素
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos);
//根据名字,查找元素
int FindSeqList(SeqList *list, char *name);
//根据名字,修改指定元素
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata);
//根据名字,删除指定元素
int DeleteSeqList(SeqList *list, char *name);
//清空表,清空表中已有元素
int ClearSeqList(SeqList *list);
//获得表中有效元素的个数
int GetSizeSeqList(SeqList *list);
//获得指定小标的元素本身
DATATYPE *GetItemSeqList(SeqList *list, int ind);
#endif

2.1 创建顺序表

SeqList *CreateSeqList(int len)
{SeqList *sl = malloc(sizeof(SeqList));if (NULL == sl){fprintf(stderr, "CreateSeqList malloc error\n");return NULL;}sl->head = malloc(sizeof(DATATYPE) * len);if (NULL == sl->head){fprintf(stderr, "CreateSeqList malloc2 error\n");return NULL;}sl->tlen = len;sl->clen = 0;return sl;
}

2.2 判断是否已满

int IsFullSeqList(SeqList *list)
{if (NULL == list){fprintf(stderr, "IsFullSeqList paramter error\n");return 1;}return list->clen == list->tlen;
}

2.3  尾插,在顺序表最后插入元素

int InsertTailSeqList(SeqList *list, DATATYPE *data)
{if (IsFullSeqList(list)){fprintf(stderr, "SeqList full\n");}memcpy(&list->head[list->clen], data, sizeof(DATATYPE));list->clen++;return 0;
}

2.4  遍历顺序表

int ShowSeqList(SeqList *list)
{int len = GetSizeSeqList(list);int i = 0;for (i = 0; i < len; ++i){printf("%s %c %d %d\n", list->head[i].name, list->head[i].sex,list->head[i].age, list->head[i].score);}return 0;
}

2.5 获得表中有效元素的个数

int GetSizeSeqList(SeqList *list) 
{ return list->clen; 
}

2.6 判断表是否为空表

int IsEmptySeqList(SeqList *list) 
{ return 0 == list->clen; 
}

2.7 根据名字,查找元素

int FindSeqList(SeqList *list, char *name)
{int i = 0, len = GetSizeSeqList(list);for (i = 0; i < len; ++i){if (0 == strcmp(list->head[i].name, name)){return i;}}return -1;
}

 2.8 获得指定下标的元素本身

DATATYPE *GetItemSeqList(SeqList *list, int ind)
{if (NULL == list){return NULL;}int len = GetSizeSeqList(list);if (ind < 0 || ind >= len){return NULL;}return &list->head[ind];
}

2.9 按指定位置插入元素

int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos)
{if (IsFullSeqList(list)){return 1;}int len = GetSizeSeqList(list);if (pos < 0 || pos > len){return 1;}int i = 0;for (i = list->clen; i > pos; i--){// Head[i] = head[i - 1];memcpy(&list->head[i], &list->head[i - 1], sizeof(DATATYPE));}memcpy(&list->head[pos], data, sizeof(DATATYPE));list->clen++;return 0;
}

2.10  根据名字,删除指定元素

int DeleteSeqList(SeqList *list, char *name)
{if (IsEmptySeqList(list)){return 1;}int ret = FindSeqList(list, name);if (-1 == ret){printf("not find\n");return 1;}else{int len = GetSizeSeqList(list);int i;for (i = ret; i < len - 1; i++){memcpy(&list->head[i], &list->head[i + 1], sizeof(DATATYPE));}list->clen--;}return 0;
}

2.11 根据名字,修改指定元素

int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata)
{if (IsEmptySeqList(list)){return 1;}int ret = FindSeqList(list, old);if (-1 == ret){printf("not find\n");return 1;}memcpy(&list->head[ret], newdata, sizeof(DATATYPE));return 0;
}

 2.12 清空表,清空表中已有元素

int ClearSeqList(SeqList *list)
{list->clen = 0;return 0;
}

2.13 销毁顺序表

int DestroySeqList(SeqList *list)
{if (NULL == list){return 1;}free(list->head);free(list);return 0;
}

三、 线性表顺序存储的优点,缺点

3.1 优点

  1. 无需为表中的逻辑关系增加额外的存储空间
  2. 可以快速随机访问元素O(1)

3.2 缺点

  1. 插入,删除元素需要移动元素o(n)
  2. 无法动态存储

四、 链表(线性表的链式存储)

        目的:解决顺序存储的缺点,插入和删除,动态存储问题

  •  特点:
  1. 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续;
  2. 可以被存储在任意内存未被占用的位置上,所以前面的顺序表只需要存储数据元素信息就可以了。在链式结构中还需要一个元素存储下一个元素的地址
  3. 为了表示每个数据元素,a[i]与其直接后继数据元素a[i+1]之间的逻辑关系,                         对a[i]来说,除了存储其本身的信息外,还需要存一个指示器直接后续的信息。
  4. 我们把存储元素信息的域叫数据域,把存储直接后继位置的域叫指针域。这两部分信息组成数据元素ai的存储映像,叫结点(Node);

4.1 单向链表

  • next指针指向整个结点开始位置
  • 自定义类型不支持嵌套定义,因为不知道分配多大的内存空间;即在typedef srtuct node中,struct node next;不可取                    但*next可取
  • 内存中开辟空间,用指针去接表头结构
typedef struct
{char name[10];char sex;int age;int score;
}DATATYPE;typedef struct _node_
{DATATYPE data;struct _node_ *next;
}LinkNode;typedef struct
{LinkNode *head;int clen;
}LinkList;

4.1.1 创建链表

LinkList *CreateLinklist()
{LinkList *ll = malloc(sizeof(LinkList));if(NULL == ll){fprintf(stderr, "CreateLinklist malloc");return NULL;}ll->head = NULL;ll->clen = 0;return ll;
}

4.1.2  判断链表是否为空

int IsEmptyLinkList(LinkList *ll)
{return  0 == ll->clen ;
}

4.1.3 头插法

(1)链表为空(直接将head指向newnode)

(2) 链表非空

int InsertHeadLinkList(LinkList *ll, DATATYPE *data)
{LinkNode *newnode = malloc(sizeof(LinkNode));if(NULL == newnode){fprintf(stderr, "InsertHeadLinkList malloc");return 1;}memcpy(&newnode->data, data, sizeof(DATATYPE));newnode->next = NULL;if(IsEmptyLinkList(ll)){ll->head = newnode;}else{newnode->next = ll->head;ll->head = newnode;}ll->clen++;return 0;
}

 4.1.4 获得表中有效元素的个数

int GetSizeLinkList(LinkList *ll)
{return ll->clen;
}

4.1.5 遍历表中元素

  • 使tmp->next来进行遍历,借助循环 
int ShowLinkList(LinkList *ll)
{int len = GetSizeLinkList(ll);LinkNode *tmp = ll->head;int i;for(i = 0; i < len; ++i){printf("%s %c %d %d \n", tmp->data.name, tmp->data.sex,tmp->data.age, tmp->data.score);tmp = tmp->next;}return 0;
}

4.1.6 根据名字,寻找元素

DATATYPE *FindLinkList(LinkList *ll, char *name)
{LinkNode *tmp = ll->head;while (tmp) {if(0 == strcmp(tmp->data.name, name)){return &tmp->data;}tmp = tmp->next;}return NULL;
}

4.1.7 根据名字,删除元素

  • 通过比较tmp下一个的内容来控制,使tmp停于待删结点的前一个结点 
int DeleteLinkList(LinkList* ll, char* name)
{LinkNode* tmp = ll->head;if (IsEmptyLinkList(ll)){return 1;}if (0 == strcmp(tmp->data.name, name)){ll->head = ll->head->next;free(tmp);ll->clen--;return 0;}while (tmp->next){if (0 == strcmp(tmp->next->data.name, name)){LinkNode* tmp2 = tmp->next;tmp->next = tmp->next->next;free(tmp2);ll->clen--;return 0;}tmp = tmp->next;}return 1;
}

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

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

相关文章

AI:人形机器人一定是人的形状吗?

本文将从技术角度分析人形机器人是否必须是人的形状&#xff0c;以及人形与非人形机器人在适用场合、优缺点上的差异。以下是详细解答&#xff1a; 人形机器人一定是人的形状吗&#xff1f; 不&#xff0c;人形机器人&#xff08;Humanoid Robot&#xff09;在技术上通常指外…

布隆过滤器和布谷鸟过滤器

原文链接&#xff1a;布隆过滤器和布谷鸟过滤器 布隆过滤器 介绍 布隆过滤器&#xff08;Bloom Filter&#xff09;是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数&#xff0c;检查值是“可能在集合中”还是“绝对不在集合中” 空间效率高&a…

无需配置光猫,使用网管交换机配合路由器的IPTV功能实现单线复用

一、背景 弱电箱和电视柜只预留了一根网线&#xff0c;路由器放在电视柜&#xff0c;想实现既可以上网又可以正常观看iptv&#xff0c;本文提供了一种方法。 二、准备工作 1、带iptv功能的路由器&#xff1b;2、水星sg105pro网管交换机&#xff1b;3、网线若干&#xff1b; …

深入理解SpringBoot中的SpringCache缓存技术

深入理解SpringBoot中的SpringCache缓存技术 引言 在现代应用开发中&#xff0c;缓存技术是提升系统性能的重要手段之一。SpringBoot提供了SpringCache作为缓存抽象层&#xff0c;简化了缓存的使用和管理。本文将深入探讨SpringCache的核心技术点及其在实际业务中的应用场景。…

2025认证杯数学建模A题思路+代码+模型:小行星轨迹预测

2025认证杯数学建模A题思路代码模型&#xff0c;详细内容见文末名片 近地小行星&#xff08; Near Earth Asteroids, NEAs &#xff09;是轨道相对接近地球的小行 星&#xff0c;它的正式定义为椭圆轨道的近日距不大于 1.3 天文单位&#xff08; AU &#xff09;的小行星。 …

LeetCode Hot100刷题——轮转数组

56. 轮转数组 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: …

「Mac畅玩AIGC与多模态41」开发篇36 - 用 ArkTS 构建聚合搜索前端页面

一、概述 本篇基于上一节 Python 实现的双通道搜索服务&#xff08;聚合 SearxNG 本地知识库&#xff09;&#xff0c;构建一个完整的 HarmonyOS ArkTS 前端页面。用户可在输入框中输入关键词&#xff0c;实时查询本地服务 http://localhost:5001/search?q...&#xff0c;返…

开源鸿蒙北向源码开发: 5.0kit化相关sdk编译

5.0kit化可以在编译系统sdk时添加,将你的kit文件加入编译使得最终生成的sdk包含kits文件 修改编译脚本 修改build仓里面的构建脚本文件,添加kits目录脚本命令 社区的build脚本已经有kits编译功能了,只需要把你的kits目录新增的kit拷贝到社区仓interface仓了,和社区的都一起编…

题单:汉诺塔问题

题目描述 如下图所示&#xff0c;设有 nn 个大小不等的中空圆盘&#xff0c;按照从小到大的顺序叠套在立柱 A 上&#xff0c;另有两根立柱 B 和 C 。 现在要求把全部圆盘从 A 柱&#xff08;称为源柱&#xff09;移到 C 柱&#xff08;称为目标柱&#xff09;&#xff0c;移动…

(面试)TCP、UDP协议

TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;是互联网核心的传输层协议&#xff0c;负责应用程序之间的数据传输。它们在设计目标、特性和适用场景上有显著差异&#xff1a; TCP&#xff1a;面向连接&#xff0c;可靠的&#xff0c;速…

uni-app小程序登录后…

前情 最近新接了一个全新项目&#xff0c;是类似商城的小程序项目&#xff0c;我负责从0开始搭建小程序&#xff0c;我选用的技术栈是uni-app技术栈&#xff0c;其中就有一个用户登录功能&#xff0c;小程序部分页面是需要登录才可以查看的&#xff0c;对于未登录的用户需要引…

通识:计算机网络基础知识

目录 计算机网络的基本组成 计算机网络的主要分类 计算机网络的功能 计算机网络的关键技术 IP地址简介 IP地址的版本 IP地址的分类 公有与私有IP地址 ​编辑 子网掩码 计算机网络基础 IPv4与IPv6对比分析 IP地址分类简化版 公有与私有IP地址 计算机网络是指将地理…

三层固定实体架构:高效实现图上的检索增强生成(RAG)

知识图谱正在成为跨各个领域组织和检索信息的强大工具。它们越来越多地与机器学习和自然语言处理技术相结合,以增强信息检索和推理能力。在本文中,我介绍了一种用于构建知识图谱的三层架构,结合了固定本体实体、文档片段和提取的命名实体。通过利用嵌入和余弦相似度,这种方…

ArcGIS Pro地块图斑顺序编号(手绘线顺序快速编号)-004

ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放_arcgis初学者使用视频-CSDN博客 4大遥感软件&#xff01;遥感影像解译&#xff01;ArcGISENVIErdaseCognition_遥感解译软件-CSDN博客 今天介绍一下在ArcGIS Pro地块图斑顺序编号&#xff08;手绘线顺序快速编号&am…

Vue百日学习计划Day21-23天详细计划-Gemini版

总目标: 在 Day 21-23 完成 Vue.js 的介绍学习、环境搭建&#xff0c;并成功运行第一个 Vue 3 项目&#xff0c;理解其基本结构。 Day 21: Vue.js 介绍与概念理解 (~3 小时) 本日目标: 理解 Vue.js 是什么、渐进式框架的概念以及选择 Vue 的原因。初步了解 Vite 是什么及其作用…

uniapp-商城-60-后台 新增商品(属性的选中和页面显示,数组join 的使用)

前面添加了属性&#xff0c;添加属性的子级项目。也分析了如何回显&#xff0c;但是在添加新的商品的时&#xff0c;我们也同样需要进行选择&#xff0c;还要能正常的显示在界面上。下面对页面的显示进行分析。 1、界面情况回顾 属性显示其实是个一嵌套的数据显示。 2、选中的…

Vue框架

Vue 概况&#xff1a; Vue是一款用于构建用户界面的渐进式的JavaScript框架。&#xff08;官方;https:://cn.vuejs.org/) 框架:就是一套完整的项目解决方案&#xff0c;用于快速构建项目。 优点:大大提升前端项目的开发效率。 缺点:需要理解记忆框架的使用规则。&#xff…

解读RTOS 第七篇 · 驱动框架与中间件集成

1. 引言 在面向生产环境的 RTOS 系统中,硬件驱动框架与中间件层是连接底层外设与上层应用的桥梁。一个模块化、可扩展的驱动框架能够简化外设管理,提升代码可维护性;而丰富的中间件生态则为网络通信、文件系统、图形界面、安全加密等功能提供开箱即用的支持。本章将从驱动模…

JavaScript防抖与节流全解析

文章目录 前言:为什么需要防抖和节流基本概念与区别防抖(Debounce)节流(Throttle)关键区别防抖(Debounce)详解1. 基本防抖函数实现2. 防抖函数的使用3. 防抖函数的工作流程4. 防抖函数进阶 - 立即执行选项节流(Throttle)详解1. 基本节流函数实现时间戳法(第一次会立即执行)定…

JavaScript入门【3】面向对象

1.对象: 1.概述: 在js中除了5中基本类型之外,剩下得都是对象Object类型(引用类型),他们的顶级父类是Object;2.形式: 在js中,对象类型的格式为key-value形式,key表示属性,value表示属性的值3.创建对象的方式: 方式1:通过new关键字创建(不常用) let person new Object();// 添…