初阶数据结构的实现1 顺序表和链表
顺序表和链表
- 1.线性表
- 1.1顺序表
- 1.1.1静态顺序表(不去实现)
- 1.1.2动态顺序表
- 1.1.2.1 定义程序目标
- 1.1.2.2 设计程序
- 1.1.2.3编写代码
- 1.1.2.3测试和调试代码
- 1.1.2 顺序表的问题与思考
- 1.2链表
- 1.2.1链表的概念及结构
- 1.2.1.1 定义程序目标
- 1.2.1.2 设计程序
- 1.2.1.3编写代码
- 1.1.2.3测试和调试代码
1.线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
相同特性
逻辑结构:人为想象出来的数据的组织形式
物理结构:数据在想象出来的数据的组织形式。
1.1顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
1.1.1静态顺序表(不去实现)
#define N 5
typedef int SLdatatype;
typedef struct SeqList {SLdatatype array [N];int size;
};
1.1.2动态顺序表
typedef int SLdatatype;
typedef struct SeqList {SLdatatype *arr;int capacity;//容量int size;//有效数据个数
}SL
1.1.2.1 定义程序目标
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef struct SeqList {SLDatatype *arr;int capacity;//容量int size;//有效数据个数
}SL;//初始化
void SLInitialize(SL*s);//销毁
void SLDestroy(SL*s );//打印顺序表
void SLPrint(SL* ps);//插入数据
//尾插
void SLPushBack(SL*s, SLDatatype x);//头插
void SLPushFront(SL*s, SLDatatype x);//尾删
void SLPopBack(SL* s);//头删
void SLPopFront(SL* s);//在指定位置插入数据
void SLInsert(SL* s, SLDatatype x, int pos);//在指定位置删除数据
void SLErase(SL* s,int pos);//查找数据
int SLFind(SL* s, SLDatatype x);
1.1.2.2 设计程序
面向程序员自身的,能实现包括顺序表的结构定义、初始化、插入、删除、查找、遍历、排序等操作
1.1.2.3编写代码
void SLInitialize(SL* ps)
{ps->arr = NULL;ps->capacity = ps->size = 0;
}void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}void SLCheckCapacity(SL* ps)
{//判断空间是否充足if (ps->size == ps->capacity){//增容//若capacity为0,给个默认值,否则×2倍int NewCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDatatype* tmp = (SLDatatype*)realloc(ps->arr, NewCapacity * sizeof(SLDatatype));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = NewCapacity;}
}void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->arr[i]);}printf("\n");
}void SLPushBack(SL*ps, SLDatatype x)
{assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}void SLPushFront(SL* ps, SLDatatype x)
{assert(ps);SLCheckCapacity(ps);//数据整体后移for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i-1];}ps->arr[0] = x;ps->size++;
}void SLPopBack(SL* ps)
{assert(ps && ps->size);ps->size--;
}
void SLPopFront(SL* ps)
{assert(ps && ps->size);for (int i = 0; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}void SLInsert(SL* ps, SLDatatype x, int pos)
{assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);for (int i = ps->size; i >pos; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[ps->size] = x;ps->size++;}void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size&& ps->size);for (int i=pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i+1];}ps->size--;
}int SLFind(SL* ps, SLDatatype x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x)return i;}return -1;
}
1.1.2.3测试和调试代码
#include"Seqlist.h"
void SLtest01()
{SL s;SLInitialize(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPushBack(&s, 5);SLPushBack(&s, 6);/*SLPushBack(NULL , 6);*/SLPushFront(&s, 1);SLPushFront(&s, 2);SLPushFront(&s, 3);SLPushFront(&s, 4);SLPrint(&s); //4 3 2 1SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopFront(&s);SLPrint(&s);SLPopFront(&s);SLPrint(&s);SLPopFront(&s);SLPrint(&s);SLPopFront(&s);SLPrint(&s);SLPopFront(&s);SLPrint(&s);SLInsert(&s, 11, 0);SLPrint(&s);SLInsert(&s, 22, s.size);SLPrint(&s);SLInsert(&s, 33, 1);SLPrint(&s);SLDestroy(&s);
}int main()
{SLtest01();return 0;
}
1.1.2 顺序表的问题与思考
- 中间/头部的插入删除,时间复杂度为O(N)
- 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
- 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们
再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
思考:如何解决以上问题呢?下面给出了链表的结构来看看。
1.2链表
1.2.1链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的 。
1.2.1.1 定义程序目标
实现
define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLTDataType;//定义结点结构;
typedef struct SListNode {SLTDataType data;struct SListNode* next;
}SLTNode;//链表的打印
void SLTPrint(SLTNode*);
//申请新结点
SLTNode* SLTBuyNode(SLTDataType);
//尾插
void SLTPushBack(SLTNode**, SLTDataType);
//头插
void SLTPushFront(SLTNode** , SLTDataType );//删除//尾删
void SLTPopBack(SLTNode**);
//头删
void SLTPopFront(SLTNode**);//查找
SLTNode* SLTFind(SLTNode*, SLTDataType);//在指定位置之前插⼊数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//在指定位置之后插⼊数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);//删除pos结点
void SLTErase(SLTNode** pphead, SLTNode* pos);//删除pos之后的结点
void SLTEraseAfter(SLTNode* pos);//销毁链表
void SListDestroy(SLTNode** pphead);
1.2.1.2 设计程序
面向程序员自身的,能实现包括链表的结构定义、初始化、插入、删除、查找、遍历、排序等操作
1.2.1.3编写代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}SLTNode* SLTBuyNode(SLTDataType x)
{SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode));if (node == NULL){perror("malloc fail");exit(1);}node->data = x;node->next = NULL;return node;
}void SLTPushBack(SLTNode**pphead, SLTDataType x)
{//申请新结点SLTNode*NewNode = SLTBuyNode(x);if (*pphead == NULL){*pphead = NewNode;}//尾结点->新结点//找尾结点else{SLTNode* pcur = *pphead;while (pcur->next){pcur = pcur->next;}pcur->next = NewNode;}
}void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);//申请新结点SLTNode* NewNode = SLTBuyNode(x);//进行头插NewNode->next = *pphead;*pphead = NewNode;
}void SLTPopBack(SLTNode** pphead)
{//链表为空不可以删除assert(pphead && *pphead);//处理链表只有一个结点的情况if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{//找prev和ptailSLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next){prev = ptail;ptail = ptail->next;}prev->next = NULL;free(ptail);ptail = NULL;}
}void SLTPopFront(SLTNode** pphead)
{//链表为空不可以删除assert(pphead && *pphead);SLTNode* next = (*pphead)->next;free(*pphead);*pphead = NULL;*pphead = next;
}SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{SLTNode* pcur = phead;while (pcur){if (pcur->data == x){return pcur;}else{pcur = pcur->next;}}return NULL;
}void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(pos);if (*pphead == pos)SLTPushBack(pphead, x);else{SLTNode* prev = *pphead;SLTNode* NewNode = SLTBuyNode(x);while (prev->next != pos){prev = prev->next;}prev->next = NewNode;NewNode->next = pos;}
}void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{assert(pos);SLTNode* NewNode = SLTBuyNode(x);NewNode->next = pos->next;pos->next = NewNode;
}void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead&&*pphead);assert(pos);if (*pphead = pos)SLTPopBack(pphead);else{SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}void SLTEraseAfter(SLTNode* pos)
{assert(pos && pos->next);SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}void SListDestroy(SLTNode** pphead)
{SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}
1.1.2.3测试和调试代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"void SListTest01()
{SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);//1->2->3->4->NULLSLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist); //4->3->2->1->NULLSLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopBack(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTPopFront(&plist);SLTPrint(plist);SLTNode* find = SLTFind(plist, 4);if (find == NULL){printf("未找到!\n");}else{printf("找到了!\n");}SLTInsert(&plist, plist, 11);//4->3->2->11->1->NULLSLTInsertAfter(plist, 11);SLTPrint(plist);1->11->2->3->4->NULLSLTErase(&plist, plist);// 1->2->3->NULLSLTEraseAfter(plist);SLTPrint(plist);SListDestroy(&plist);SLTPrint(plist);
}
int main()
{SListTest01();return 0;
}
相关文章:
初阶数据结构的实现1 顺序表和链表
顺序表和链表 1.线性表1.1顺序表1.1.1静态顺序表(不去实现)1.1.2动态顺序表1.1.2.1 定义程序目标1.1.2.2 设计程序1.1.2.3编写代码1.1.2.3测试和调试代码 1.1.2 顺序表的问题与思考 1.2链表1.2.1链表的概念及结构1.2.1.1 定义程序目标1.2.1.2 设计程序1.…...
破解反爬虫策略 /_guard/auto.js(一) 原理
背景 当用代码或者postman访问一个网站的时候,访问他的任何地址都会返回<script src"/_guard/auto.js"></script>,但是从浏览器中访问显示的页面是正常的,这种就是网站做了反爬虫策略。本文就是带大家来破解这种策略&…...
40.简易频率计(基于等精度测量法)(3)
(1)BCD8421码:十进制数字转换成BCD8421码的方法 补零:你需要显示多少位数字,就在前面补上四倍的位宽。比如你要显示一个十进制8位的数字,就在前面补上8*432个零。判断:判断补零部分显示的十进制…...
关于Centos停更yum无法使用的解决方案
最近在使用Centos7.9系统时候,发现yum仓库无法进行安装软件包了,官方说2024年6月30日进行停更,停更后无法提供对应的软件服务。 我在使用yum安装包的时候发现确实不能使用官方服务了: CentOS停更的影响 CentOS停止更新之后&#…...
插画感言:成都亚恒丰创教育科技有限公司
插画感言:笔触间的灵魂对话 在这个快节奏、高压力的时代,我们时常在寻找那些能够触动心灵、让灵魂得以片刻栖息的角落。而插画,这一融合了艺术与情感的独特形式,便如同一股清泉,缓缓流淌进每个人的心田,以…...
【算法】数组中的第K个最大元素
难度:中等 题目: 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题…...
Perl 语言的特点
Perl 语言入门学习可以涵盖多个方面,包括其特点、基本语法、高级特性以及学习资源和社区支持等。以下是一个详细的入门学习指南: 一、Perl 语言的特点 文本处理能力强:Perl 提供了丰富的字符串处理函数和正则表达式的支持,非常适…...
NLP教程:1 词袋模型和TFIDF模型
文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型: 词集模型:单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个。 词袋模型:在词集的基础上如果一个单词…...
【开源 Mac 工具推荐之 2】洛雪音乐(lx-music-desktop):免费良心的音乐平台
旧版文章:【macOS免费软件推荐】第6期:洛雪音乐 Note:本文在旧版文章的基础上,新更新展示了一些洛雪音乐的新功能,并且描述更为详细。 简介 洛雪音乐(GitHub 名:lx-music-desktop )…...
AMEYA360:思瑞浦推出汽车级理想二极管ORing控制器TPS65R01Q
聚焦高性能模拟芯片和嵌入式处理器的半导体供应商思瑞浦3PEAK(股票代码:688536)发布汽车级理想二极管ORing控制器TPS65R01Q。 TPS65R01Q拥有20mV正向调节功能,降低系统损耗。快速反向关断(Typ:0.39μs),在电池反向和各种汽车电气瞬…...
简约的悬浮动态特效404单页源HTML码
源码介绍 简约的悬浮动态特效404单页源HTML码,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head><meta charset="utf-8&q…...
Golang 创建 Excel 文件
经常会遇到需要导出数据报表的需求,除了可以通过 encoding/csv 导出 CSV 以外,还可以使用 https://github.com/qax-os/excelize 导出 xlsx 等格式的 excel,下面封装了一个方法,支持多 sheet 的 excel 数据生成,导出按需…...
探索GitHub上的两个革命性开源项目
在数字世界中,总有一些项目能够以其创新性和实用性脱颖而出,吸引全球开发者的目光。今天,我们将深入探索GitHub上的两个令人惊叹的开源项目:Comic Translate和GPTPDF,它们不仅改变了我们处理信息的方式,还极…...
SpringBoot框架学习笔记(三):Lombok 和 Spring Initailizr
1 Lombok 1.1 Lombok 介绍 (1)Lombok 作用 简化JavaBean开发,可以使用Lombok的注解让代码更加简洁Java项目中,很多没有技术含量又必须存在的代码:POJO的getter/setter/toString;异常处理;I/O…...
【ASP.NET网站传值问题】“object”不包含“GetEnumerator”的公共定义,因此 foreach 语句不能作用于“object”类型的变量等
问题一:不允许遍历 原因:实体未强制转化 后端: ViewData["CateGroupList"] grouplist; 前端加上:var catelist ViewData["CateGroupList"] as List<Catelogue>; 这样就可以遍历catelist了 问题二:…...
Stateflow中的状态转换表
状态转换表是表达顺序模态逻辑的另一种方式。不要在Stateflow图表中以图形方式绘制状态和转换,而是使用状态转换表以表格格式表示模态逻辑。 使用状态转换表的好处包括: 易于对类列车状态机进行建模,其中模态逻辑涉及从一个状态到其邻居的转换…...
结合Redis解决接口幂等性问题
结合Redis解决接口幂等性问题 引言正文收获 引言 该问题产生背景是根据需求描述,要求对已发布的课程能进行编辑修改,并且要求能进行回滚。 幂等性问题描述:对同一个接口并发请求产生的结果是不变的。 Get 请求以及 Delete 请求天然保证幂等…...
2024算力基础设施安全架构设计与思考(免费下载)
算网安全体系是将数据中心集群、算力枢纽、一体化大数据中心三个层级的安全需求进行工程化解耦,从国家安全角度统筹设计,通过安全 服务化方式,依托威胁情报和指挥协同通道将三层四级安全体系串联贯通,达成一体化大数据安全目标。 …...
ExoPlayer架构详解与源码分析(15)——Renderer
系列文章目录 ExoPlayer架构详解与源码分析(1)——前言 ExoPlayer架构详解与源码分析(2)——Player ExoPlayer架构详解与源码分析(3)——Timeline ExoPlayer架构详解与源码分析(4)—…...
网络安全-等级保护制度介绍
一、等保发展历程 (1)1994国务院147号令 第一次提出等级保护概念,要求对信息系统分等级进行保护 (2)1999年GB17859 国家强制标准发布,信息系统等级保护必须遵循的法规 (3)2005年公安…...
【介绍下大数据组件之Storm】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...
React Hook 总结(React 萌新升级打怪中...)
1 useCallback useMemo 和 useCallback 接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于 useMemo 返回的是函数运行的结果,useCallback 返回的是函数。 当需要使用 useCallback 的情况通常包括以…...
Typora 1.5.8 版本安装下载教程 (轻量级 Markdown 编辑器),图文步骤详解,免费领取
文章目录 软件介绍软件下载安装步骤激活步骤 软件介绍 Typora是一款基于Markdown语法的轻量级文本编辑器,它的主要目标是为用户提供一个简洁、高效的写作环境。以下是Typora的一些主要特点和功能: 实时预览:Typora支持实时预览功能࿰…...
mac docker no space left on device
mac 上 docker 拉取镜像报错 Error response from daemon: write /var/lib/docker/tmp/docker-export-3995807640/b8464f52498789c4ebbc063d508f04e8d2586567fbffa475e3cd9afd3c5a7cf2/layer.tar: no space left on device解决: 增加 docker 虚拟磁盘大小。如下图...
单片机主控的基本电路
论文 1.复位电路 2.启动模式设置接口 3.VBAT供电接口 4.MCU 基本电路 5.参考电压选择端口...
【19】读感 - 架构整洁之道(一)
概述 《架构整洁之道》一书中有提到设计和架构的感念,它们究竟是什么?书是这么说的,它们的层次不一样,架构更“高层级”的说法,这类讨论一般都把“底层”的实现细节排除在外。而设计往往指代的具体的系统底层组织结构…...
多层全连接神经网络(三)---分类问题
问题介绍 机器学习中的监督学习主要分为回归问题和分类问题,我们之前已经讲过回归问题了,它希望预测的结果是连续的,那么分类问题所预测的结果就是离散的类别。这时输入变量可以是离散的,也可以是连续的,而监督学习从数…...
签名优化:请求数据类型不是`application/json`,将只对随机数进行签名计算,例如文件上传接口。
文章目录 I 签名进行请求数据类型类型判断1.1 常见的ContentType1.2 签名切面处理1.3 文件上传案例1.4 处理接口信息背景: 文件上传接口的请求数据类型通常为multipart/form-data,方便携带文本域和使用接口文档进行调试。 如果携带JSON数据,不方便调试接口。 前端数据也要特…...
PostgreSQL的Json数据类型如何使用
PostgreSQL中的JSON数据类型提供了一种灵活的方式来存储JSON(JavaScript Object Notation)数据。JSON是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在PostgreSQL中,你可以使用JSON和JSONB&…...
SpringData JPA Mongodb 查询部分字段
JPA 网上用的好像不多,找了好多材料以后最终找了这个可行的方案: Query(fields "{tender_id:1,_id:0}")List<MGPltTender> findByTenderIdIsNotNull(PageRequest pageRequest); 调用: Sort sort Sort.by(popularType.getC…...
wordpress修改管理员/如皋网站制作
ContOS7.5 python2.7.5 离线升级 python3.7.41. 第一步:下载安装包 解压2. 第二步:执行安装2.1 创建存放目录2.2 运行脚本 configure2.2.1 注意:2.3 make编译make install安装2.4 最后运行make clean3. 第三步:创建软连接4. 总结报…...
q王商城 网站是怎么做的/网络营销策划模板
一:共享账号检查 配置名称:用户账号分配检查,避免共享账号存在 配置要求:1、系统需按照实际用户分配账号; 2、避免不同用户间共享账号,避免用户账号和服务器间通信使用的账号共享。 操作指南&…...
做app模板网站有哪些/免费做网站怎么做网站链接
当然可以!这是一个使用辗转相除法来求最大公约数的 Java 程序示例: public class GCD {public static void main(String[] args) {int a = 24;int b = 36;int gcd = findGCD(a, b);System.out.println("最大公约数是:" + gcd);}...
广告素材网站哪个比较好/深圳网络推广哪家公司好
1.今天使用 _itoa函数,出现蛋疼的问题原来又是微软的一套。 2.如何解决呢? 在第一行添一句:#define _CRT_SECURE_NO_WARNINGS //关闭安全检查 代码如下: 1 #define _CRT_SECURE_NO_WARNINGS2 # include<stdio.h>3 # …...
google网站建设/seo排名优化方式方法
被这玩意坑了2个多小时。 ----------------------------------- 由于 android studio 在建项目时,不会自动识别 so 文件,所以在含有so 文件的项目中,需要在 build.gradle 中加入 sourceSets { main() { jniLibs.srcDirs [libs] } } 不加入&a…...
java如何做网站/网站联盟
MUI 下拉刷新 浏览器正常但是手机端不显示下拉的等待文字下拉刷新不显示等待文字:PC浏览器打开正常,但是手机端却没有。检查后发现手机上运行时,没有进到下面的_initPocket方法中,但是为什么PC和手机端会表现不一致。不知道该如何…...