当前位置: 首页 > news >正文

83.【C语言】数据结构之顺序表的尾部插入和删除

目录

3.操作顺序表

2."伪"插入顺序表的元素

分析尾部插入函数SLPushBack

代码示例

SeqList.h

main.c

free(指针)出错的几种可能的原因

3."伪"删除顺序表元素

2.分析尾部删除函数SLPopBack

代码示例

错误检查

两种解决办法

1.判断size是否为负数

2.assert断言size的大小(直接强制终止运行)


承接82.【C语言】数据结构之顺序表的初始化和销毁的3.操作顺序表

3.操作顺序表

2."伪"插入顺序表的元素

四个"伪"插和"伪"删函数

在SeqList.h中再写入:

void SLPushBack(SL* ps,SLDataType x);//尾部插入
void SLPopBack(SL* ps);//尾部删除
void SLPushFront(SL* ps, SLDataType x);//头部插入
void SLPopFront(SL* ps);//头部删除

关于命名的问题:在汇编里,push为入栈(在这里理解为插入),pop为出栈(在这里理解为删除),front为头部,back为尾部

分析尾部插入函数SLPushBack

注意事项

1.每插入一个元素,ps->size++

2.空间不够,需要扩容(realloc)(添加一个判断size和capacity的大小的语句,判断realloc的返回值是否为空指针)

代码示例

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>typedef int SLDataType;//将int重定义为SLDataType
#define INIT_CAPACITY 4
typedef struct Seqlist
{SLDataType* a;//动态顺序表int size;//有效数据的个数int capacity;//空间的容量
}SL;void SLInit(SL* ps);//声明初始化顺序表的函数
void SLDestory(SL* ps);//声明销毁顺序表的函数
void SLPushBack(SL* ps, SLDataType x);//尾部插入
void SLPopBack(SL* ps);//尾部删除
void SLPushFront(SL* ps, SLDataType x);//头部插入
void SLPopFront(SL* ps);//头部删除
void SLPrint(SL* ps);//打印结构

main.c

#include "SeqList.h"
//定义测试顺序表的函数
void TestSeqList1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPrint(&s);SLDestory(&s);
}int main()
{TestSeqList1();return 0;
}

SeqList.c

#include "SeqList.h"
void SLInit(SL* ps)
{ps->a = (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);if (ps->a == NULL){perror("malloc");return;//错误返回}ps->size = 0;ps->capacity = INIT_CAPACITY;
}void SLPushBack(SL* ps, SLDataType x)
{if (ps->size == ps->capacity)//size>capacity会越界{//扩大2倍较为合适SLDataType* tmp = (SLDataType*)realloc(ps->a, ps->capacity * 2);if (tmp == NULL){perror("realloc");return;//错误返回}ps->capacity *= 2;ps->a = tmp;//新扩容空间的指针赋值给ps->a}ps->a[ps->size++] = x;//写入数据
}void SLPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}
}void SLDestory(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}

a4672af08a254e0d9f7330ae0ff10a1a.png

如果多添加几行则会出问题

	SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPushBack(&s, 5);SLPushBack(&s, 6);

c07d68fe180c4423ae6347ff28ecc5a9.png

free(指针)出错的几种可能的原因

1.没有从头开始释放空间

2.越界访问(下标越界或空间开辟过少)

这里为第2种情况

改为

SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType)*ps->capacity * 2);

成功运行

b2b113af22164940891749f2dd41da61.png

3."伪"删除顺序表元素

2.分析尾部删除函数SLPopBack

代码示例

头部删除,只需要修改有效个数size的大小即可,不需要修改动态内存的数据

main.c改为

#include "SeqList.h"
//定义测试顺序表的函数
void TestSeqList1()
{SL s;SLInit(&s);SLPushBack(&s, 1);SLPushBack(&s, 2);SLPushBack(&s, 3);SLPushBack(&s, 4);SLPushBack(&s, 5);SLPushBack(&s, 6);SLPushBack(&s, 7);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLPrint(&s);SLPopBack(&s);SLDestory(&s);
}int main()
{TestSeqList1();return 0;
}

SeqList.c写入

void SLPopBack(SL* ps)
{ps->size--;
}

这样写 ps->a[ps->size--] = 0; 没有必要

错误检查

其实上方的代码写的有问题!

多次调用SLPopBack函数可能使size为负数

两种解决办法

1.判断size是否为负数

void SLPopBack(SL* ps)
{if (ps->size == 0){return;//错误返回}ps->size--;
}

2.assert断言size的大小(直接强制终止运行)

void SLPopBack(SL* ps)
{assert(ps->size > 0);ps->size--;
}

运行结果:

注:有关assert的详细介绍在39.【C语言】指针(重难点)(D)

如果设计头部插入SLPushFront函数和头部删除SLPopFront函数,需要移动其他元素使其向后排,执行效率不高

以下来自《计算机科学导论 第四版》的部分内容

dd5a0391b880435f841cb43266a5e47b.png

c36eee5d4510454a9914e9a0101bed9c.png

c543b52e30594f6ca88a818dc484e4d9.png


http://www.mrgr.cn/news/53601.html

相关文章:

  • C语言 | Leetcode C语言题解之第493题翻转对
  • [实时计算flink]DataStream连接器设置方法
  • 骑砍霸主MOD天芒传奇Ⅱ·前传-序章
  • Cuda By Example - 8 (性能测量)
  • ChatGPT的150个角色提示场景实测(17)营养师
  • 一天认识一个硬件之路由器
  • MobaXterm 中文乱码
  • 22 linux 进程管理进程间通信
  • 【JAVA毕业设计】基于Vue和SpringBoot的图书个性化推荐系统
  • pip安装sentence-transformers时的一些报错记录以及Python汉字转拼音cleverdeng/pinyin.py程序的调整处理
  • 高效实现Python机器学习:超参数优化中的网格搜索与随机搜索详解
  • 城市发展指数-基于滴滴平台数据测算
  • C++ 数组、递归两种方式实现二分查找
  • 安卓窗口wms/input小知识NO_INPUT_CHANNEL剖析
  • Python无监督学习中的聚类:K均值与层次聚类实现详解
  • 【厦门大学附属第一医院(互联网医院)-注册安全分析报告-无验证方式导致安全隐患】
  • 大模型量化感知训练 LLM-QAT
  • 深度学习框架-Keras的常用内置数据集总结
  • 妇女、商业与法律(WBL)(1971-2023年)
  • 理解ADC:信噪比SNR的天花板是什么?附带介绍一下ENOB