C语言.数据结构.顺序表

1.顺序表的概念及结构

1.1线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.顺序表的分类

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

  • 顺序表的分类

    • 静态顺序表
      概念:使用定长数组储存元素
      在这里插入图片描述

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

    • 动态顺序表
      在这里插入图片描述

优先使用动态顺序表,因为其更加灵活。

3.动态顺序表的实现

3.1文件的选取

  1. 头文件.h
    定义顺序表的定义、声明顺序表的方法
  2. 源文件.c
    实现顺序表的方法
  3. 测试文件.c
    检测代码是否能够按照预期运行

3.2动态顺序表的定义:

//定义顺序表的结构
typedef int SLDataType;//动态顺序表
typedef struct SeqList
{SLDataType* arr;int size;//有效数据个数int capacity;//空间大小
}SL;

3.2顺序表的打印:

//顺序表的打印
void SLPrint(SL ps)
{//遍历顺序表for (int i = 0; i < ps.size; i++){printf("%d ", ps.arr[i]);}printf("\n");
}

3.3顺序表的查找

//顺序表的查找
int SLFind(SL* ps, SLDataType x)
{//遍历顺序表assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){//找到后,就返回下标return i;}}//遍历一遍,没有找到,就返回-1;(数组下标不能为负数)return -1;
}

3.4申请空间

//申请空间
void SLCheckCapacity(SL* ps)
{//再插入数据前,先看空间够不够if (ps->capacity == ps->size){//申请空间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;}
}

解释:

  1. capacity = size的时候,证明顺序表的空间与有效数据一样了,已经空间塞满,再插入数据就插不进去了。
  2. int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;

1)假如顺序表空间为零,就直接赋值为4个空间大小。
2)假如顺序表空间不为零,就以顺序表的空间大小的2倍申请空间。



3.4顺序表的初始化

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

理解:

  1. 顺序表的底层是数组,arr代表的是数组首元素的地址,先置换为空。
  2. 再让顺序表的空间大小(capacity)置为0,也让有效数据(size)置为空。

3.5顺序表的尾部插入

//尾部插入
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//等价于assert(ps != NULL)//再插入数据前,先看空间够不够if (ps->capacity == ps->size){//申请空间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;}//进行尾插ps->arr[ps->size++] = x;
}

解释:

  1. 问题:一次要申请多大的空间?

增容通常来讲是成倍数的增加,一般是2或3倍。 实际上是数学推理出来的。假若频繁的增容,则会造成程学的运行效率大大的降低。

画图分析:

在这里插入图片描述

3.7顺序表的头部插入

//头部插入
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++;
}

画图分析:

在这里插入图片描述

3.7顺序表的尾部删除

//尾部删除
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//有效数据不为空//直接使有效数据减少--ps->size;
}

画图分析:

在这里插入图片描述

3.8顺序表的头部删除

//头部删除
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//数据整体往前移动一位for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];//arr[size-2] = arr[size-1]}//有效数据自减1ps->size--;
}

画图分析:

在这里插入图片描述

3.9在指定位置之前插入数据

//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//pos的范围要在顺序表的size范围之内assert(pos >= 0 && pos <= ps->size);//在插入数据前,看看顺序表的空间够不够SLCheckCapacity(ps);//让pos及之后的数据整体往后移动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];//}//空出pos位置,插入数据ps->arr[pos] = x;//有效数据自增1ps->size++;
}

画图分析:

在这里插入图片描述

3.10在指定为位置删除数据

//在指定为位置删除数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//遍历顺序表,让pos之后的数据整体往前移动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}//有效数据自减1ps->size--;
}

画图分析:

在这里插入图片描述

3.11顺序表的销毁

//顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr)//等价于if(ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}

4.整体代码展示

SqeList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>//定义顺序表的结构
typedef int SLDataType;//动态顺序表
typedef struct SeqList
{SLDataType* arr;int size;//有效数据个数int capacity;//空间大小
}SL;//顺序表的打印
void SLPrint(SL ps);//顺序表的查找
int SLFind(SL* ps, SLDataType x);//顺序表初始化
void SLInit(SL* ps);//尾部插入
void SLPushBack(SL* ps, SLDataType x);//头部插入
void SLPushFront(SL* ps, SLDataType x);//尾部删除
void SLPopBack(SL* ps);//头部删除
void SLPopFront(SL* ps);//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);//在指定为位置删除数据
void SLErase(SL* ps, int pos);//顺序表的销毁
void SLDestroy(SL* ps);

SqeList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"//顺序表的打印
void SLPrint(SL ps)
{//遍历顺序表for (int i = 0; i < ps.size; i++){printf("%d ", ps.arr[i]);}printf("\n");
}//申请空间
void SLCheckCapacity(SL* ps)
{//再插入数据前,先看空间够不够if (ps->capacity == ps->size){//申请空间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;}
}//顺序表的查找
int SLFind(SL* ps, SLDataType x)
{//遍历顺序表assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){//找到后,就返回下标return i;}}//遍历一遍,没有找到,就返回-1;(数组下标不能为负数)return -1;
}//顺序表初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->capacity = ps->size = 0;
}//尾部插入
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//等价于assert(ps != NULL)//再插入数据前,先看空间够不够if (ps->capacity == ps->size){//申请空间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;}//进行尾插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);assert(ps->size);//有效数据不为空//直接使有效数据减少--ps->size;
}//头部删除
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//数据整体往前移动一位for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];//arr[size-2] = arr[size-1]}//有效数据自减1ps->size--;
}//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);//pos的范围要在顺序表的size范围之内assert(pos >= 0 && pos <= ps->size);//在插入数据前,看看顺序表的空间够不够SLCheckCapacity(ps);//让pos及之后的数据整体往后移动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];//}//空出pos位置,插入数据ps->arr[pos] = x;//有效数据自增1ps->size++;
}//在指定为位置删除数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//遍历顺序表,让pos之后的数据整体往前移动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}//有效数据自减1ps->size--;
}//顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr)//等价于if(ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"void SLTest()
{SL sl;//顺序表初始化SLInit(&sl);//尾部插入SLPushBack(&sl, 1);SLPushBack(&sl, 2);SLPushBack(&sl, 3);SLPushBack(&sl, 4);//顺序表的打印SLPrint(sl);SLPushFront(&sl, 1);SLPushFront(&sl, 2);SLPushFront(&sl, 3);SLPushFront(&sl, 4);SLPrint(sl);//尾部删除SLPopBack(&sl);SLPrint(sl);//头部删除SLPopFront(&sl);SLPrint(sl);//顺序表的查找int ret = SLFind(&sl, 4);if (ret < 0){printf("找不到!\n");}else{printf("找到了!\n");}//在指定位置之前插入数据int ret = SLFind(&sl, 1);SLInsert(&sl, ret, 5);SLPrint(sl);//在指定为位置删除数据int ret = SLFind(&sl, 2);SLErase(&sl, ret);SLPrint(sl);//顺序表的销毁SLDestroy(&sl);
}int main()
{SLTest();return 0;
}

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

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

相关文章

闲鱼电商运营高级课程,一部手机学会闲鱼开店赚钱(34节课)

课程目录 1&#xff0c;闲鱼更货出售主要核心原理.mp4 2、闲鱼前期开店准备.mp4 3.账号基础信息设置1.mp4 4、提升账号权重.mp4 5、注意避免违规行为.mp4 6、实接课 应该怎么选择爆款产品.mp4 7、分析商品的闲鱼市场.mp4 8、寻找最低价货源.mp4 9、怎么寻我优质的货源…

VOS3000被DDOS攻击后该怎么办

VOS3000遭受DDoS攻击的应对措施 当VOS3000遭受DDoS攻击时&#xff0c;可以采取以下几个步骤来应对&#xff1a; 立即启动防火墙&#xff1a;尽管难以完全阻止DDoS攻击&#xff0c;但防火墙可以在一定程度上帮助抵御攻击&#xff0c;减轻其造成的危害。 联系服务器提供商&#…

634 · 单词矩阵

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; . - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a; class Solution { public: struct Trie {Trie() {next.resize(26, nullptr);end false;} std::vector<Trie*> next; b…

视频监控技术前沿探索:智能化趋势与EasyCVR视频汇聚技术应用

在数字化时代的浪潮中&#xff0c;视频监控技术以其独特的优势&#xff0c;正在安防领域书写着新的篇章。它不仅为公共安全部门提供了强大的技术支持&#xff0c;还深入到教育、政府、娱乐、医疗、酒店、运动等多个领域&#xff0c;成为维护社会秩序、保障人民安全的重要工具。…

LearnOpenGL(二十)之立方体贴图

一、创建立方体贴图 首先&#xff0c;生成一个纹理&#xff0c;并将其绑定到纹理目标GL_TEXTURE_CUBE_MAP&#xff1a; unsigned int textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); 因为立方体贴图包含有6个纹理&#xff0…

Pytorch深度学习实践笔记3

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;pytorch深度学习 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 视频来自【b站刘二大人】 目录 1 梯度下降&#…

【机器学习系列】使用高斯贝叶斯模型进行数据分类的完整流程

目录 一、导入数据 二、选择特征 三、十折交叉验证 四、划分训练集和测试集 五、训练高斯贝叶斯模型 六、预测测试集 七、查看训练集和测试集上的分数 八、查看混合矩阵 九、输出评估指标 一、导入数据 # 根据商户数据预测其是否续约案例 import pandas #读取数据到 da…

2022蓝桥杯大赛软件类国赛Java大学B组 左移右移 空间换时间+双指针

import java.util.Scanner;public class Main {static Scanner scnew Scanner(System.in);public static void main(String[] args) {int nsc.nextInt();//数组长度int tsc.nextInt();//操作次数int arr[]new int[n];char arr1[] new char[t];int arr2[] new int[t];int vis…

C++ RBTree封装mapset

目录 RBTreeNode的声明 RBTree结构 map结构 set结构 改造红黑树 迭代器类 迭代器成员函数 默认成员函数 Insert set map RBTreeNode的声明 template<class T> struct RBTreeNode {RBTreeNode<T>* _left;RBTreeNode<T>* _right;RBTreeNode<T>*…

非等值连接、等值连接、自然连接

目录 一、笛卡尔积 二、三种连接的关系 三、非等值连接 四、等值连接 五、自然连接 一、笛卡尔积 要理解非等值连接、等值连接、自然连接首先要理解笛卡尔积。 学过《离散数学》的应该很熟悉笛卡尔积。 简单来说&#xff0c;就是有两个集合&#xff0c;其中一个集合中的元…

第五十四周:文献阅读

目录 摘要 Abstract 文献阅读&#xff1a;基于经验模态分解的混合空气质量预测模型 现有问题 提出方法 方法论 1、扩展ARIMA模型 2、经验模态分解&#xff08;EMD&#xff09; 3、截断奇异值分解&#xff08;SVD&#xff09; SE-ARIMA模型 研究实验 1、数据集 2、评…

如何从U盘恢复误删除的文件

在许多情况下&#xff0c;用户可能会发现其U盘上的数据误删&#xff0c;并且无法访问或恢复它。在这篇文章中&#xff0c;我们将看到如何使用命令提示符尝试从U盘恢复损坏的文件和数据。我们还将列出一些免费的U盘恢复软件及其独特的功能&#xff0c;以便在前一种方法无法产生所…

北邮22级信通院DSP:用C++程序实现给定参数下四种滤波器的Butterworth模拟滤波器设计:给定上下截频和衰减系数求H(p)和H(s)

北邮22信通一枚~ 跟随课程进度更新北邮信通院DSP的笔记、代码和文章&#xff0c;欢迎关注~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院DSP_青山入墨雨如画的博客-CSDN博客 目录 一、 核心算法 1.1判断滤波器类型 1.2 带通滤波器BP 1.3带阻滤波器B…

分享:大数据风险检测报告,哪里查询比较好?

随着大数据技术的发展&#xff0c;逐渐被运用到各个领域&#xff0c;基于大数据技术的个人风险检测也就是我们常说的大数据报告在金融环境中运用的十分普遍&#xff0c;那大数据风险检测报告哪里查询比较好呢?本文就为大家简单介绍一下。 大数据风险检测报告查询能查到什么? …

Ubuntu coredump文件的生成并利用gdb查看报错位置

1.开启core文件生成 相关链接&#xff1a;gdb调试core dump使用 - 知乎 (zhihu.com) 相关链接&#xff1a;ubuntu | linux下程序崩溃生成coredump的方法_linux崩溃dump-CSDN博客 &#xff08;1&#xff09;ulimit -c unlimited &#xff08;2&#xff09;echo "/tmp/cor…

在ubuntu中关于驱动得问题:如何将nouveau驱动程序加入黑名单和安装NVIDIA显卡驱动

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、nouveau驱动程序加入黑名单二、安装NVIDIA显卡驱动 一、nouveau驱动程序加入黑名单 (1) 打开黑名单列表文件 终端输入&#xff1a; sudo gedit /etc/modprobe…

HarmonyOS开发之DevEco Studio安装

HUAWEI DevEco Studio是基于IntelliJ IDEA Community开源版本打造&#xff0c;为运行在HarmonyOS和OpenHarmony系统上的应用和服务&#xff08;以下简称应用/服务&#xff09;提供一站式的开发平台。 作为一款开发工具&#xff0c;除了具有基本的代码开发、编译构建及调测等功能…

Linux程序开发(十二):线程与多线程同步互斥实现抢票系统

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

自己手写一个栈【C风格】

#include <iostream> //栈 #define MAX_SIZE 20 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0typedef int Status;//状态类型 typedef int ElemType;//元素类型typedef struct SqStack {ElemType data[MAX_SIZE];int top; };//初始化&#xff0c;方法1 …

CSAPP(datalab)解析

howManyBits /* howManyBits - 返回用二进制补码表示x所需的最小位数* 示例: howManyBits(12) 5* howManyBits(298) 10* howManyBits(-5) 4* howManyBits(0) 1* howManyBits(-1) 1* howManyBits(0x80000000) …