顺序表复习(C语言版)

数据结构是什么?

数据结构就是为了把数据管理起来,方便我们的增删查改

数据结构是计算机存储、组织数据的方式

数组就是一种最基础的数据结构

 

顺序表是什么?

顺序表就是数组

Int arr[100] = {1,2,3,4,5,x,……}

修改某个数据:arr[pos] = x

插入某一个数据:找数组中已有元素个数,再插入数据

删除某一个数据:找数组中已有元素个数,再删除数据

顺序表说:虽然我底层逻辑是数组,但是我提供了很多现成的方法,开箱即用,我就变成了一个新的很厉害的数据结构

所以数据结构就是在数组基础上增加了赠删查改的方法

  数组                       数据结构

苍蝇馆子                   米其林

炒土豆丝                 豪华金丝(土豆丝+摆盘)

顺序表是线性表的一种(线性表为具有相同特性的数据结构的组合),同时线性表可以存放任何类型的数据

例如苹果、香蕉都是水果

物理结构(数据在内存存储时的结构):线性表不一定是线性的,但顺序表绝对是

逻辑结构(想象出来的结构):顺序表一定是线性

0f9b77f90e9d40729f949d1d7ad5731e.jpg

 注:左边是逻辑结构,是人抽象而得的;右边是物理结构,七扭八歪,是现实中真实情况

 

顺序表的分类:

int arr[10] = {0} 定长的数组

Int* arr:指针可以动态内存开辟(realloc增容,malloc开辟),确认大小之后再去动态申请

顺序表分类

静态顺序表:

struct SeqList{int arr[100];int size;};

顺序表当前有效的数据个数 假设为1,插入1个新的元素进去,size变成2

 

动态顺序表:

struct SeqList{int* arr;int size;int capacity;};

当下的空间大小,100个空间到1000个空间

动态开辟了100个空间,存放数据,0的范围为0<=size<=100

动态顺序表优于静态顺序表

静态顺序表,给小了空间不够用;给大了,造成空间浪费

将这样的结构体命名成Seqlist的原因:

sequence(Seq):顺序                                   list:列表

 

动态增容(成倍数的增加,一般以一倍or二倍的倍数增加)

若频繁增容,则会造成程序运行效率大大降低

顺序表的开始与初始化:

00abc450178e4f8eb869268c104673fb.jpg

.h文件就像一本书的目录,里面会有不同内容具体在哪一页的明细

#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef int SLDataType; //下述讲解(图)//定义顺序表的结构
struct Seqlist
{int* arr; //顺序表存储的有效数据个数不确定int size; //顺序表存储的有效数据个数int capacity; //空间大小
};
typedef struct Seqlist SL; //方便后续使用//线性表初始化、增删查改的声明
void SLinit(SL ps);
……;//在.h文件中

03b17d0619204abe917e4a17612c768d.jpg

 用beidi来命名int,计算机中的int就有两种命名方式;这样能便于大型项目的修改,并同时还能满足部分修改的需要

//线性表初始化
#include"Seqlist.h" //只有引用该头文件之后,才可以使用头文件中创建好的结构体
void SLinit(SL s)
{s.arr = NULL; //初始情况下没有开辟空间,因此为NULLs.size = s.capacity = 0; //初始情况下没有数据,因此都为0
}//在.c文件中
//stdlib.h 和 stdio.h 的引用可以放在.h文件中
#include"Seqlist.h"void SLtest01()
{SL sl;SLinit(s1);
}int main()
{SLtest01();return 0;
}
//在.c文件中

测试函数和主函数讲解此处省略

开始调试时,上述代码会报错,说我们使用了未初始化的局部变量"sl"

d213393ea2084047babd402cc5f37177.jpg

 函数在传参时,非指针变量形式的形参是个临时变量,出了函数就自动销毁了;而指针变量形式的形参才是真正改变地址中的数据的;因此我们需要将实际参数取地址,将形式参数变量指针变量的形式,即:

void SLinit(SL* s)
SLinit(&s1)

同时,因为是结构体指针,因此线性表初始化函数中的表示形式也需要更改,具体如下

void SLinit(SL* s)
{s->arr = NULL; //初始情况下没有开辟空间,因此为NULLs->size = s->capacity = 0; //初始情况下没有数据,因此都为0
}

 

顺序表的销毁:

void SLdestory(SL* s)
{if (s->arr){free(s->arr);}s->arr = NULL;s->size = s->capacity = 0;
}

释放空间,变成空指针,把使用完的size和capacity再次变成0

 

顺序表的插入:

尾插:

1ee3eb64425647b3b823490362745ed9.jpg

上图是插入前的情况,数组下标从0开始算

d4d5ab4bf6154af79a4cd9cca0b0dd7f.jpg

上图是插入后情况,size下标处被放入了5

void SLpushback(SL* s, SLDataType x)
{//if (s == NULL)//{//	return;//} //预防指针为空,增加代码的健壮性,以上是方法1assert(s); //即assert(s!=NULL)//以上是方法2,在用assert断点时需要引用头文件assert.h//插入数据之前先看空间够不够if (s->capacity == s->size){//申请空间,增容用realloc函数int newcapacity = s->capacity == 0 ? 4 : 2 * s->capacity;  
//初始化时,capacity为0,可以在此让他变成4;也可以直接在初始化时使用malloc函数开辟一个空间,让capacity变成自己想要的大小,但请注意malloc函数开辟应该是对arr指针而言SLDataType* tmp = (SLDataType*)realloc(s->arr, newcapacity * 2 * sizeof(SLDataType));
//realloc返回值为万能指针,因此需要强制转换,2*newcapacity还不够,因为不同类型字节大小不一,因此需要乘上SLDataType的大小,更多动态内存开辟相关内容详见下文链接if (tmp == NULL){perror("realloc fail"); //realloc函数开辟失败会返回一个空指针,tmp接收了exit(1); //直接退出程序,不再继续执行}//代码到这说明空间申请成功s->arr = tmp;s->capacity = newcapacity; //让顺序表内容变成新值}s->arr[s->size++] = x; //++为后置++,先用后加
}

动态内存开辟文章链接:https://blog.csdn.net/2302_80297338/article/details/136792864?spm=1001.2014.3001.5501

 

头插:

头插时先判断空间够不够,然后将所有数据从后完全向后移动,因为从前往后会将原有数据一并掩盖掉,最后别忘了size的加一

80958084b2ea4bcb95c4086f42872d3d.jpg

​
void SLpushfront(SL* s, SLDataType x)
{assert(s);SLcheck(s); //判断空间需不需要增容的函数(上文已经讲解过)//先让顺序表中已有的数据整体往后挪动一位for (int i = s->size; i >= 1; i--){s->arr[i] = s->arr[i - 1]; //arr[1]=arr[0]是最后一次循环}s->arr[0] = x; //将值插入s->size++;
}

 

顺序表的删除:

尾删:

尾删后,size减少1,但需要判断好顺序表是否为空

c1fa470846644330853d6fdd751e13ef.jpg

void SLpopback(SL* s)
{assert(s);assert(s->size); //顺序表不能为空s->size--; //不管尾部放-1还是放0,因为size--,最后打印时都不会出现
}

头删:

不需要再对头部所需删除的元素进行操作,直接将后续元素向前移动一位,头部元素自然而然就被覆盖了

e5e21749862146f6a8450ae3989932d3.jpg

void SLpopfront(SL* s)
{assert(s);for (int i = 0; i <= s->size - 2; i++){s->arr[i] = s->arr[i + 1]; //最后一次循环是arr[size-2]=arr[size-1]}s->size--;
}

 

顺序表的插入:

假如我要在pos=2的位置插入,那么就需要先把原有数据从后往前向后移动一位,最后在空出来的开头位置放入所需存放的元素

a37cc0fd421843118f897a0f88294228.jpg

					 //location  //elementvoid SLInsert(SL* s, int pos, SLDataType x)
{assert(s);//ps不能为0assert(pos >= 0 && pos <= s->size); //所插位置大于等于0,小于等于有效数据才是尾插int i;SLcheck(s); //插入数据:空间够不够?//开始挪动for (int i = s->size; i >= pos+1; i--) {s->arr[i] = s->arr[i - 1]; //最后一次循环是arr[pos + 1] = arr[pos]}s->arr[i] = x; //把要存放的数据放入s->size++;
}

 

顺序表的指定位置删除:

8ac70add70474977b457b5c83006edb8.jpg

删除情况下,size和pos还能否相等?

答案是不能,因为size作为数组下标没有任何指向的元素,pos等于size相当于数组越界访问,应该用assert断点杜绝这样的事情发生

将pos后的元素从前到后向前移动一位,pos位置的元素被覆盖,自然完成指定位置删除的功能

105435f4c3a04a6a9c2b1a219b1954ed.jpg

	void SLpop(SL* s, int pos){assert(s); //ps不能为空assert(pos >= 0 && pos < s->size);for (int i = pos; i < s->size - 1; i++)  //i < size-2{s->arr[i] = s->arr[i + 1];  //arr[size-2] = arr[size-1] }s->size--;}

 

顺序表的查找:

遍历整个顺序表,找到该元素返回该元素下标,如果没找到就返回任意一个非数组下标的数,接收,if语句来打印“没找到”

	int SLFind(SL* s, SLDataType x)  //x为需查找的数据{assert(s);for (int i = 0; i < s->size; i++){if (s->arr[i] == x){//找到啦,返回需要查找的值的数组下标return i;}}//没有找到return -1;}
//返回以后请用整型变量接收,并打印

 

更多顺序表相关知识:

之后我会写一点顺序表相关的leetcode例题,敬请期待~

 

 

 

 

 

 

 

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

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

相关文章

Mac下删除旧版本.net sdk

参照微软官网给的方法,Releases dotnet/cli-lab (github.com) 好像不能直接的解决问题,我做一下补充,希望对需要删除旧版本sdk的小伙伴们有所帮助 1:下载工具包 Releases dotnet/cli-lab (github.com) 2:打开终端,cd切换到该文件的制定目录 3:然后按照提示一步步执行…

java核心类

一,String字符串 1.1,String字符串是引用类型,且不可变 String str1 "Hello";String str2 str1.concat(" World"); // 使用concat方法连接字符串&#xff0c;返回一个新的字符串对象System.out.println(str1); // 输出&#xff1a;Hello&#xff0c;原始…

C语言:复习

文章目录 思维导图数组和指针库函数的模拟实现判断大小端 最近知识学的差不多了&#xff0c;因此开始复习&#xff0c;本篇开始的是对于C语言的复习 思维导图 下面就依据下图&#xff0c;进行内容的整理 数组和指针 这个模块算是C语言中比较大的一个模块了&#xff0c;具体概…

流媒体协议--RTMP

文章目录 RTMP播放基本流程TCP握手过程RTMP握手过程connect连接createStream 创建流play 播放命令deleteStream删除流RTMP数据组成 RTMP(Real Time Messaging Protocol)是一个应用层协议&#xff0c;主要用于在Flash player和服务器之间传输视频、音频、控制命令等内容。 该协议…

【笔试强训_Day06】

文章目录 1.字符串相乘 1.字符串相乘 题目链接 解题思路&#xff1a; 高精度乘法&#xff0c;注意要学会下面这种列式相乘的形式&#x1f34e; 注意细节❗&#xff1a; ① &#x1f34e; 首先把列式相乘的数据都存放到数组中去&#xff0c; 然后再对数组中的数据进行取余进…

C++:运算符重载和“const”成员

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;运算符重载》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 赋值运算符重载1. 运算符重载2.赋值运算符重载第一个点第二个点&…

迅雷下载不了的资源怎么下载?

我想下载Boost库&#xff0c;但是下载不下来 用迅雷下载是一直卡在0k 后来尝试在centos上用wget进行下载&#xff0c;竟然可以 wget https://boostorg.jfrog.io/artifactory/main/release/1.85.0/source/boost_1_85_0.tar.gz

揭开ChatGPT面纱(一):准备工作(搭建开发环境运行OpenAI Demo)

文章目录 序言&#xff1a;探索人工智能的新篇章一、搭建开发环境二、编写并运行demo1.代码2.解析3.执行结果 本博客的gitlab仓库&#xff1a;地址&#xff0c;本博客对应01文件夹。 序言&#xff1a;探索人工智能的新篇章 随着人工智能技术的飞速发展&#xff0c;ChatGPT作为…

2024燃动智火-业务视角的中国企业AI+学习发展报告

来源&#xff1a;新华三 学习型组织的数字化转型是众多企业关注的焦点&#xff0c;数字战略需要人才升级&#xff0c;数字 化学习加速人才培养。AI 技术在学习中的运用&#xff0c;为企业学习型组织的数字化转型插 上了飞翔的翅膀。这份报告解码了AI 时代企业的学习发展&#…

混合现实(MR)开发框架

混合现实&#xff08;MR&#xff09;开发框架为开发者提供了构建MR应用程序所需的基本工具和功能。它们通常包括3D引擎、场景图、输入系统、音频系统、网络功能以及支持同时处理现实世界和虚拟世界信息的功能。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&…

springboot+ssm基于Java的小型企业银行账目管理系统代码Lw

本毕业设计课题要求学生基于软件工程方法&#xff0c;根据课题的需求&#xff0c;给出小型企业银行账目管理系统概要设计、详细设计、数据库的设计以及系统实现和测试&#xff0c;并撰写规范的毕业设计说明书。该系统的主要模块有&#xff1a;系统管理、帐目管理、查询统计、用…

如何使用 ArcGIS Pro 制作边界晕渲效果

在某些出版的地图中&#xff0c;边界有类似于“发光”的晕渲效果&#xff0c;这里为大家介绍一下如何使用ArcGIS Pro 制作这种晕渲效果&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的行政区划数据&#xff0c;除了行政区划数据&#xff0c…

【Flutter】多语言方案二:GetX 版

介绍 多语言方案&#xff1a;GetX版&#xff0c;需要手动自定义字符串引用常量&#xff0c;优点不需要自己管理状态。 目录 介绍运行效果一、安装 GetX二、使用1.语言配置 在lib/core下创建一个language文件夹&#xff0c;文件夹下创建一个local.dart文件2.language文件夹下创…

程序员自由创业周记#32:新产品构思

程序员自由创业周记#32&#xff1a;新产品构思 新作品 我时常把自己看做一位木匠&#xff0c;有点手艺&#xff0c;能做一些作品养活自己。而 加一、Island Widgets、Nap 就是我的作品。 接下来在持续维护迭代的同时&#xff0c;要开启下一个作品的创造了。 其实早在2022的1…

进程间通信(1)管道

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

【C语言】内存函数-memcpy-memmove-memset...用法及实现,沉淀自己!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. memcpy函数使用和模拟实现 2. memmove使用和模拟实现 3. memset函数的使用 4. memcmp函数的使用 1. memcpy函数使用和模拟实现 <string.h>-------…

Buildroot系统构建学习笔记(以百问网imx6ullPro开发板为例)

一、Builroot是什么&#xff1f; Buildroot是一组Makefile和补丁&#xff0c;可简化并自动化地为嵌入式系统构建完整的、可启动的Linux环境(包括bootloader、Linux内核、包含各种APP的文件系统)。Buildroot运行于Linux平台&#xff0c;可以使用交叉编译工具为多个目标板构建嵌…

沉思录 (梁实秋)

链接&#xff1a;https://pan.quark.cn/s/8e27564b02f5

Python 检测当前系统的内存及硬盘资源,发送邮件告警通知(告警内容包含告警语句及网卡和系统版本时间)

颜色块 rootbogon:~ 2024-04-18 16:16:40# cat DefaultColor.py ######################################################################### # File Name: DefaultColor.py # Author: eight # Mail: 18847097110163.com # Created Time: Thu 11 Apr 2024 10:…

H3C之GRE VPN

华子目录 GRE实验测试 MGRE实验 GRE实验 第一步&#xff1a;接口配置IP地址 <H3C>sys System View: return to User View with CtrlZ. [H3C]sysname r1 [r1]int g0/0 [r1-GigabitEthernet0/0]ip add 192.168.1.1 24 [r1-GigabitEthernet0/0]int g0/1 [r1-GigabitEtherne…