数据结构入门(3)1:顺序表接口实现

前言

本文将一一介绍顺序表基本功能的接口实现,帮助大家提高编程能力,加深对数据结构的理解

本文将以动态顺序表为主进行解释

基本接口功能

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLDataType;
typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SeqList;//常用接口
//顺序表初始化
void SeqListInit(SeqList* psl);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

 顺序表初始化

将顺序表结构体里的成员变量该置0置0,该置空置空,因为在创建初,成员变量存放的都是随机值,整型存放的是随机数,指针指向的是随机地址,如果不初始化就进行调用的话,容易导致内存错误。

同时将顺序表指针断言一下,以免传入空指针。

void SeqListInit(SeqList* psl)
{assert(psl);psl->a = NULL;psl->size = 0;psl->capacity = 0;
}

检查容量函数 

动态顺序表的好处就是,我们可以根据需要判断是否需要扩容,因为扩容函数方便。设想一下,如果是静态顺序表的话(用数组存储的顺序表),就得一开始创建好,定好容量后就不能改变了,过多且不说,万一少了咋办,而且多了话还会浪费不必要的内存。

实现原理:

当顺序表内元素个数等于最大容量就扩容,且每次是双倍扩容,但是当最大容量为0时(创建初)将最大容量设置为4即可,这是考虑到了0*任何数都等于0的情况。

动态顺序表,利用动态内存管理相关的函数relloc申请内存分配。

这里提一下,因为relloc的功能是在已经通过动态申请的内存上进行扩大或缩小,但当创建初,顺序的表的指针为空,则此时realloc的功能就等于malloc。

void CheckCapacity(SeqList* psl)
{assert(psl);if (psl->size == psl->capacity){int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;//双倍扩容SLDataType* ptr = (SLDataType*)realloc(psl->a, sizeof(SLDataType) * newcapacity);if (ptr == NULL){perror("return fail");return;}psl->a = ptr;psl->capacity = newcapacity;}
}

顺序表尾插 

这是顺序表插入元素最简单的方法,但每次插入前,记得使用一下检查容量函数,插入后,个数size记得加1.

void SeqListPushBack(SeqList* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);psl->a[psl->size++] = x;
}

 顺序表尾删

直接size--就行,被剪掉的那个元素会被丢弃

void SeqListPopBack(SeqList* psl)
{assert(psl);assert(psl->size != 0);psl->size--;
}

顺序表头插

头插有讲究,不能直接像尾插那样直接放数据进去,那样第一个元素就被覆盖掉了,所以就得将整个数组的元素位置向后移一个,将数组按照从后往前的顺序整体往后移(避免覆盖丢失数据),这样数组的头一个元素就空出来了,此时才能往里放数据。

和尾插一样,检查一下容量,size++。

void SeqListPushFront(SeqList* psl, SLDataType x)
{assert(psl);CheckCapacity(psl);int end = psl->size - 1;for (int i = end; i >= 0; i--){psl->a[i + 1] = psl->a[i];}psl->a[0] = x;psl->size++;
}

顺序表头删

头删和头插一样有讲究,将数组头后面的元素整体向前移完成覆盖,从头往后的顺序向前移,移完后记得将size--。

void SeqListPopFront(SeqList* psl)
{assert(psl);assert(psl->size != 0);int begin = 1;while (begin < psl->size){psl->a[begin - 1] = psl->a[begin];begin++;}psl->size--;
}

顺序表查找

没什么好说的,就是简单的数组查找

int SeqListFind(SeqList* psl, SLDataType x)
{assert(psl);for (int i = 0; i < psl->size; i++){if (psl->a[i] == x){return i+1;}}return 0;
}

顺序表在pos位置插入x

不管是什么插入,都要检查一下容量。

先找到对应的pos位置,将pos后面的所有数组,按照从后往前的顺序向后移,之后再进行插入,记得size++。

void SeqListInsert(SeqList* psl, int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos <= psl->size);CheckCapacity(psl);int end = psl->size - 1;while (end >= pos){psl->a[end + 1] = psl->a[end];end--;}psl->a[pos] = x;psl->size++;}

顺序表删除pos位置的值

和上面的一个原理,但不一样的是将pos后面的数组按从前往后的顺序往前移实现覆盖,记得size--。

void SeqListErase(SeqList* psl, size_t pos)
{assert(psl);assert(pos >= 0 && pos < psl->size);int begin = pos + 1;int end = psl->size - 1;while (begin <= end){psl->a[begin - 1] = psl->a[begin];begin++;}psl->size--;
}

顺序表销毁

该置0置0,该freefree,记得将free后的指针置空。

void SeqListDestory(SeqList* psl)
{assert(psl);if (psl->a != NULL){free(psl->a);psl->capacity = 0;psl->size = 0;}
}

顺序表打印 

void SeqListPrint(SeqList* psl)
{assert(psl);for (int i = 0; i < psl->size; i++){printf("%d ", psl->a[i]);}printf("\n");
}

以上这些就是顺序表的基本功能实现细节,虽然都一一列了出来,但还是希望各位能够去根据每一个功能的思想自己写出来,加深印象。

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

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

相关文章

【原创 附源码】Flutter集成谷歌支付详细流程(附源码)

最近有时间&#xff0c;特意整理了一下之前使用过的Flutter平台的海外支付&#xff0c;附源码及demo可供参考 这篇文章只记录Google支付的详细流程&#xff0c;相关Flutter文章链接如下&#xff1a; 【原创 附源码】Flutter集成Apple支付详细流程(附源码) 【原创 附源码】Flu…

【大数据Hive】hive 表设计常用优化策略

目录 一、前言 二、hive 普通表查询原理 2.1 操作演示说明 2.1.1 创建一张表&#xff0c;并加载数据 2.1.2 统计3月24号的登录人数 2.1.3 查询原理过程总结 2.2 普通表结构带来的问题 三、hive分区表设计 3.1 区表结构 - 分区设计思想 3.2 操作演示 3.2.1 创建分区表…

解决MAC连上wifi或热点却不能上网问题

解决MAC连上wifi或热点却不能上网问题 #新换的mac昨天还能连上wifi&#xff0c;今天就不好使了。 找到连接的wifi点击详细信息&#xff0c;选择TCP/IP 中的配置IPV4 选择关闭

独孤思维:绝版书副业又优化了

做副业&#xff0c;不光要低头干活&#xff0c;还要抬头看路。 我做绝版书那会&#xff0c;实操的心得和经验会分享给学员。 学员实操久了&#xff0c;就会在自己实操的过程中&#xff0c;总结自己的经验。 有些经验&#xff0c;比独孤的还好。 比如上周&#xff0c;群里有…

Python Matplotlib 的学习笔记

Python Matplotlib 的学习笔记 0. Python Matplotlib 简介1. 为什么要用 Matplotlib&#xff1f;2. Matplotlib 基础类详解2-1. Line&#xff08;线&#xff09;2-2. Marker&#xff08;标记&#xff09;2-3. Text&#xff08;文本&#xff09;2-4. Legend&#xff08;图例&…

Vue3-01

Vue.js &#xff08;通常简称为 Vue&#xff09;是一套用于构建用户界面的渐进式框架。与其他框架不同的是&#xff0c;Vue采用了自底向上增量开发的设计。Vue的核心库只关注视图层&#xff0c;并且非常容易与现有项目集成。Vue也完全支持通过插件的方式进行扩展。Vue的设计理念…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-arm ads下的start.S分析(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd1688 提取码&#xff1a;1688 ; ; NAME: 2440INIT.S ; DESC: C start up codes ; Configure memory, ISR ,stacks ; Initialize C-variables ; 完全注释 ; HISTORY: ; 2002.02.25:kwtark: ver 0.…

中国电子学会2023年12月份青少年软件编程Scratch图形化等级考试试卷一级真题(含答案)

2023-12 Scratch一级真题 分数&#xff1a;100 题数&#xff1a;37 测试时长&#xff1a;60min 一、单选题(共25题&#xff0c;共50分) 1.观察下列每个圆形中的四个数&#xff0c;找出规律&#xff0c;在括号里填上适当的数&#xff1f;&#xff08;C&#xff09;&#xf…

预处理详解(下)

1.#运算符 #运算符将宏的一个参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执行的操作可以理解为”字符串化“。 例如&#xff1a; 我们将打印的字符串中的n改为参数n,这样在传参的时候就也会随着变化。假如我们不将其改为参数n的话会发生什么呢…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(3) 保存表格数据

对上两篇篇的工作C Qt框架开发| 基于Qt框架开发实时成绩显示排序系统&#xff08;1&#xff09;-CSDN博客和C Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统&#xff08;2&#xff09;折线图显示-CSDN博客继续优化&#xff0c;增加一个保存按钮&#xff0c;用于保存成绩数据…

论文阅读-面向机器学习的云工作负载预测模型的性能分析

论文名称&#xff1a;Performance Analysis of Machine Learning Centered Workload Prediction Models for Cloud 摘要 由于异构服务类型和动态工作负载的高变异性和维度&#xff0c;资源使用的精确估计是一个复杂而具有挑战性的问题。在过去几年中&#xff0c;资源使用和流…

给定n个结点的树,其中有k个结点是特殊结点(未知),定义好结点:该结点到k个特殊结点的距离之和最小。若随机k个结点为特殊结点,求好结点个数的期望值

题目 思路: 举例: 其中黑色结点为特殊结点,可以看出,每种情况都有一个结点的s值不等于k / 2,但是是好结点,所以最后答案加一。 #include <bits/stdc++.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second …

支持向量机SVM

支持向量机&#xff08;SVM&#xff0c;Support Vector Machines&#xff09;是一种广泛使用的监督学习方法&#xff0c;适用于分类、回归和其他任务。SVM的核心思想是找到一个最优的决策边界&#xff08;在二维空间中是一条线&#xff0c;在更高维度是一个超平面&#xff09;&…

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类

【北邮鲁鹏老师计算机视觉课程笔记】10 Classification 分类 1 图像识别的基本范式 检测问题&#xff1a;不仅要知道有没有&#xff0c;还要知道在哪里 分类是整图级标签&#xff0c;检测是区域级标签&#xff0c;分割是像素级标签 2 检测任务的应用 3 单实例识别与类别识别…

问题 J: 今年暑假不AC

题目描述 “今年暑假不AC&#xff1f;” “是的。” “那你干什么呢&#xff1f;” “看世界杯呀&#xff0c;笨蛋&#xff01;” “#$%^&*%...” 确实如此&#xff0c;世界杯来了&#xff0c;球迷的节日也来了&#xff0c;估计很多ACMer也会抛开电脑&#xff0c;奔向电视…

【5G NR】【一文读懂系列】移动通讯中使用的信道编解码技术-Turbo编码原理

目录 Turbo码&#xff1a;无线通信中的革命性技术 引言 一、Turbo码的基本原理 1.1 卷积码基础&#xff1a; 1.2 Turbo码的构造&#xff1a; 1.2.1 分量编码器 1.2.2 随机交织器 1.2.3 穿刺和复接单元 1.3 编码器结构的重要性和影响 1.4 迭代解码&#xff1a; 1.4.1 …

接口测试怎么进行,如何做好接口测试

一、什么是接口&#xff1f; 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点&#xff0c;定义特定的交互点&#xff0c;然后通过这些交互点来&#xff0c;通过一些特殊的规则也就是协议&#xff0c;来进行数据之间的交互。 二、 常用接口采用方式&#x…

AI少女/HS2甜心选择2 仿剑三剑灵人物卡全合集打包

AI少女/HS2甜心选择2 仿剑三剑灵人物卡全合集打包 内含&#xff1a;菩提禅音[剑网3]明教晓天喵姐[剑3]明教晓天喵姐无帽版[剑3]茱莉亚[剑灵] 下载地址&#xff1a; https://www.changyouzuhao.cn/12492.html

配置DNS正反向解析服务!!!!

一.准备工作 #关闭防火墙和selinux,或者允许服务通过 [rootnode ~]# nmcli c mod ens32 ipv4.method manual ipv4.address 192.168.32.133/24 ipv4.gateway 192.168.32.2 ipv4.dns 192.168.32.132 [rootnode ~]# nmcli c reload [rootnode ~]# nmcli c up ens32[rootnode ~]# …

高速网络之翼:探索UDP的力量与灵活性

引言 在计算机网络中&#xff0c;用户数据报协议&#xff08;UDP&#xff09;是一种简单的面向数据报的传输层协议。与传输控制协议&#xff08;TCP&#xff09;相比&#xff0c;UDP不提供可靠性保证&#xff0c;但它因其低延迟和低开销的特性而在特定应用中非常有用。UDP使得…