数据结构-->线性表-->顺序表

news2024/12/29 9:16:43

对我个人来说,C语言基础相关的知识基本学完了,随后就该学数据结构了,希望以后自己复习能够用上今天自己写的哈哈。

如果你不理解什么是物理结构和逻辑结构,这里附上一个链接:逻辑结构和物理结构:逻辑结构与物理结构_逻辑结构和物理结构-CSDN博客

 

看见我的备注了吗,一位不帅的帅哥。

数据结构的相关介绍

我们将数据结构拆分为两个词来理解
数据就是存储的信息,结构是组织数据的方式。
官方定义的数据结构的概念为:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。数据结构反应数据的内部构成,即数据有哪部分构成,以什么方式构成,以及数据元素之间呈现的结构。
总结:

(1)能够存储数据(顺序表,链表等结构)
(2)存储的数据能够方便查找

数组是最基础的数据结构,我们除了数组还要学习更多数据结构的原因是:最基础的数据结构能够提供的操作已经不能完全满足复杂算法实现。

对数据结构中线性表的认识

线性表:

线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列

线性表在逻辑上是线性结构,也就是说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常是以数组和链式结构的形式存储。

从顺序表开始启航

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

顺序表分为静态顺序表和动态顺序表。

对静态顺序表来说:空间给少了不够用,给多了造成空间浪费。

也就是说老年机的通讯录就是静态顺序表。

这里附上老年机,商标就打码了,怕吃官司。

 因此我们就写动态版本的顺序表了

对学校数据结构方面的忠告

 好的,其实到这里呢,我就去手搓动态顺序表了,哈哈,幸运的是我完全写出来了,没看别人的,老师说过数据结构这块呢,就是要熟悉,重要的是代码,其实我觉得呢也没有别的办法,多写才是解药。

顺序表头文件

代码的头文件

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size;
	int capacity;
}SL;

//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);
//打印
void SLPrint(SL* ps);
//扩容
void SLCheck(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps);
//头插
void SLPushFront(SL* ps, SLDataType x);
//头删
void SLPopFront(SL* ps);
//查找
int FindData(SL* ps, SLDataType x);
//指定位置插入
void InsertPush(SL* ps, int pos, SLDataType x);
//指定位置删除
void ErasePop(SL* ps, int pos);

初始化

这里没什么难度,就直接写就ok

//初始化
void SLInit(SL* ps)
{
    ps->a = NULL;
    ps->capacity = ps->size = 0;
}

 销毁

程序结束记得销毁,否则会发生内存泄漏,切记、切记、切记。

//销毁
void SLDestroy(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

打印

对于打印,其实就直接遍历就ok

//打印
void SLPrint(SL* ps)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
}

扩容

这里的扩容,顾名思义就是扩大空间,他的作用是为了提供足够的空间

//扩容
void SLCheck(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* new = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (new == NULL)
		{
			perror("REALL0C FAIL");
			return;
		}
		ps->a = new;
		ps->capacity = newcapacity;
	}
}

尾插

尾插我们先检查我们的空间大小够不够,对于需要插入的接口来说,我们都要检查空间是否足够,

只要空间足够,就直接插入就ok了。

//尾插
void SLPushBack(SL* ps,SLDataType x)
{
	assert(ps);
	SLCheck(ps);
	ps->a[ps->size++] = x;
}

尾删 

直接把size减去1就ok

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

头插

头插就是要把原来的数据往后挪动,但是不能从前往后挪动,因为这样会覆盖之后还没挪动的数据,因此我们需要把数据从后往前开始往后挪动 

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheck(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;
}

头删

头删跟头插正好相反,额这算不算相当于没说

就是把数据从前往后开始往前面移动 

//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	for (int i = 1; i < ps->size; i++)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

 查找

查找就是遍历再加一层比较,值相等就返回下标

//查找
int FindData(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

指定位置插入

其实就是类似头插,注意for循环范围别搞错了,如果你怕搞错,这里提供一种方法,就是你只比较带入for循环的最大和最小情况,如果成立,那就是正确的。

//指定位置插入
void InsertPush(SL* ps, int pos, SLDataType x)
{
    assert(ps);
    assert(ps->size);
    assert(pos >= 0 && pos <= ps->size);
    for (int i = ps->size; i > pos; i--)
    {
        ps->a[i] = ps->a[i - 1];
    }
    ps->a[pos] = x;
    ps->size++;
}

指定位置删除

 类似头删

//指定位置删除
void ErasePop(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos + 1; i < ps->size; i++)
	{
		ps->a[i - 1] = ps->a[i];
	}
	ps->size--;
}

最后附上最终代码 

总代码

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size;
	int capacity;
}SL;

//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);
//打印
void SLPrint(SL* ps);
//扩容
void SLCheck(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps);
//头插
void SLPushFront(SL* ps, SLDataType x);
//头删
void SLPopFront(SL* ps);
//查找
int FindData(SL* ps, SLDataType x);
//指定位置插入
void InsertPush(SL* ps, int pos, SLDataType x);
//指定位置删除
void ErasePop(SL* ps, int pos);

SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
//初始化
void SLInit(SL* ps)
{
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
//销毁
void SLDestroy(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
//打印
void SLPrint(SL* ps)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
}
//扩容
void SLCheck(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* new = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (new == NULL)
		{
			perror("REALL0C FAIL");
			return;
		}
		ps->a = new;
		ps->capacity = newcapacity;
	}
}
//尾插
void SLPushBack(SL* ps,SLDataType x)
{
	assert(ps);
	SLCheck(ps);
	ps->a[ps->size++] = x;
}
//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}
//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheck(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;
}
//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	for (int i = 1; i < ps->size; i++)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}
//查找
int FindData(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
//指定位置插入
void InsertPush(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(ps->size);
	assert(pos >= 0 && pos <= ps->size);
	for (int i = ps->size; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}
//指定位置删除
void ErasePop(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos + 1; i < ps->size; i++)
	{
		ps->a[i - 1] = ps->a[i];
	}
	ps->size--;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
int main()
{
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);//1 2
	SLPrint(&s);
	printf("\n");
	SLPopBack(&s);//1
	SLPrint(&s);
	printf("\n");
	SLPushFront(&s,2);//2 1
	SLPrint(&s);
	printf("\n");
	SLPopFront(&s);//1
	SLPrint(&s);
	SLDestroy(&s);
	return 0;
}

 运行test函数,测试各接口是否正确

运行一下test函数,检查一下

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

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

相关文章

c语言贪食蛇游戏

演示视频 目录 一.概述 二.游戏开始前 修改控制台程序标题和大小 Win32 API GetStdHandle函数 GetConsoleCursorInfo函数和SetConsoleCursorInfo函数 SetConsoleCursorPosition函数 游戏开篇界面处理 创建地图 蛇身节点以及食物节点初始化 蛇身的初始化 整体蛇节点…

通过 docker-compose 部署 Flink

概要 通过 docker-compose 以 Session Mode 部署 flink 前置依赖 Docker、docker-composeflink 客户端docker-compose.yml version: "2.2" services:jobmanager:image: flink:1.17.2ports:- "8081:8081"command: jobmanagervolumes:- ${PWD}/checkpoin…

JSDoc 注释规范

JSDoc 注释 在 前端项目中&#xff0c;注释格式包含了一些特殊标记&#xff0c;如 param、returns 等&#xff0c;这种注释通常是用来标记函数或方法的参数和返回值的数据类型和描述。 这种注释格式通常被称为 JSDoc 注释。在实际开发中&#xff0c;这样的注释可以被一些工具解…

[总结]HTML+JS逆向混淆混合

国外的题果然考得与众不同 [secrypt_cen.html] 这次是HTML网页&#xff0c;然后JS加密判断 翻看JS代码 {width"5.75in" height"3.375in"} 很显然&#xff0c;关键的代码在checkPassword JS混淆是必备的 去混淆一条龙走起 先将关键代码提取出来 JavaScriptf…

Java项目使用jasypt加密和解密配置文件中关键信息

一、使用背景 项目中application.yml 配置文件中&#xff0c;如数据库、redis、加密算法的私钥等各种配置的username&#xff0c;password的值都是明文的&#xff0c;其实存在一定的安全隐患&#xff0c;如果被人拿到这些配置文件&#xff0c;将直接对系统安全构成极大威胁&…

Python库-PyAutoGUI

pyautogui是一个Python库&#xff0c;可以自动控制键盘和鼠标&#xff0c;非常适合进行自动化任务。它可以用于各种场景&#xff0c;比如自动化测试、数据录入任务&#xff0c;甚至是简单的游戏机器人。下面是一个关于pyautogui的入门教程&#xff0c;包括它的安装、基本使用方…

Hadoop-IDEA开发平台搭建

1.安装下载Hadoop文件 1&#xff09;hadoop-3.3.5 将下载的文件保存到英文路径下&#xff0c;名称一定要短。否则容易出问题&#xff1b; 2&#xff09;解压下载下来的文件&#xff0c;配置环境变量 3&#xff09;我的电脑-属性-高级设置-环境变量 4.详细配置文件如下&#…

python-分享篇-屏保计时器

文章目录 代码效果 代码 import turtle, time def drawGap():turtle.penup()turtle.fd(5) def drawLine(draw):drawGap()turtle.pendown() if draw else turtle.penup()turtle.fd(40)drawGap()turtle.right(90) def drawDigit(d):drawLine(True) if d in [2,3,4,5,6,8,9] else…

一台Mac同时安装vue2和vue3

背景&#xff1a;电脑需要运行vue2和vue3项目&#xff0c;就得同时有vue2和vue3环境&#xff0c;之前以配置好vue2了&#xff0c;现在增加vue3 1. 新建一个安装vue3的目录 进入vue3文件夹安装vue3 // 注意这里没有参数-g&#xff0c;因为-g全局安装的命令 npm install vue/cli…

laravel distinct查询问题,laravel子查询写法

直接调用后&#xff0c;count查询会和实际查询的数据对不上&#xff0c;count还是查询全部数据&#xff0c;而实际的列表是去重的。 给distinct加上参数&#xff0c;比如去重的值的id&#xff0c;就加id。 另一种写法是使用group by id 子查询。 sql语句&#xff1a; selec…

介绍 MSTest Runner – CLI、Visual Studio 等

作者&#xff1a;Amaury Lev Marco Rossignoli Jakub Jareš 排版&#xff1a;Alan Wang 我们很高兴推出 MSTest 运行器&#xff0c;这是一款全新的轻量级 MSTest 测试运行器。这个新的运行器使测试更加便携和可靠&#xff0c;运行速度更快&#xff0c;并且具有可扩展性&#x…

如何安装x11vnc并结合cpolar实现win远程桌面Deepin

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff…

【C++】基础知识讲解(命名空间、缺省参数、重载、输入输出)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;http://t.csdnimg.cn/eCa5z 目录 命名空间 命名空间的定义 命名空间的使用 命名空间的嵌套使用 C输入&输出 std命名空间的使用惯例&…

穿越周期,海信稳居全球第二的底气和底盘

【潮汐商业评论/原创】 颠覆创新&#xff0c;凡墙皆是门&#xff0c;而因循守旧&#xff0c;凡门皆是墙。 面对充满不确定性的时代&#xff0c;用什么驱散迷雾走向增长&#xff1f;这是当下中国大部分企业所面临的困惑。 选择用什么答案来应对这个问题&#xff0c;也决定了企…

stable-diffusion | v1-5-pruned.ckpt和v1-5-pruned-emaonly.ckpt的区别

https://github.com/runwayml/stable-diffusion?tabreadme-ov-file#reference-sampling-script 对于 1.5 模型&#xff0c;其中可能包括四部分&#xff1a;标准模型、文本编码器、VAE模型、EMA模型。 标准模型&#xff1a;生成图片的核心模块&#xff0c;潜空间中的前向扩散和…

【Django】Django中的缓存

缓存 1 缓存的定义 定义&#xff1a;缓存是一类可以更快的读取数据的介质统称&#xff0c;也指其他可以加快数据读取的存储方式&#xff0c;一般用来存储临时数据&#xff0c;常用介质的是读取速度很快的内存。 意义&#xff1a;视图渲染有一定成本&#xff0c;数据库的频繁查…

电力负荷预测 | Matlab实现基于LSTM长短期记忆神经网络的电力负荷预测模型(结合时间序列)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 电力负荷预测 | Matlab实现基于LSTM长短期记忆神经网络的电力负荷预测模型(结合时间序列) 所谓预测,就是指通过对事物进行分析及研究,并运用合理的方法探索事物的发展变化规律,对其未来发展做出预先估计和判断…

UE4 C++创建摄像机摇臂和相机并且设置Transform

新建MyPawn C类 .h #include "GameFramework/SpringArmComponent.h" //SpringArm组件 #include "Camera/CameraComponent.h" //Camera组件class 工程名称_API AMyPawn : public APawn { //定义组件变量 public:UPROPERTY(VisibleAnywhere, BlueprintRead…

【数据库原理及应用】简答题归纳总结

第一章 数据库概论 1.人工管理阶段数据管理的特点&#xff1a; &#xff08;1&#xff09;数据不保存在机器中 &#xff08;2&#xff09;无专用的软件对数据进行管理 &#xff08;3&#xff09;只有程序的概念&#xff0c;没有文件的概念 &#xff08;4&#xff09;数据面向程…

2024-02-06 TCP/UDP work

1. 画出TCP三次握手和四次挥手的示意图&#xff0c;并且总结TCP和UDP的区别 三次握手&#xff1a; 4次挥手&#xff1a; tcp/udp区别 TCP 1. 稳定&#xff0c;提供面向连接的&#xff0c;可靠的数据传输服务 2. 传输过程中&#xff0c;数据无误、数据无丢失、数据无失序、…