动态顺序表的详解(下)

简介: 动态顺序表的详解(下)

顺序表的尾删

有了尾插也一定有尾删,直接看代码。

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

由于是尾部删除,我们只需要将最后一个数据丢失即可,我们舍弃最后一个数据,只需要通过psl指针找到的size–即可。

顺序表的头删

有了头插也一定有头删,看一下吧。

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

首先,依然是断言保证传入指针非空,保证有效数据个数不为0,之后我们需要从开始将第二个元素赋给第一个元素,再把第三个元素赋给第二个元素,这样下去,就能实现头删,我们定义一个begin变量为1,在while循环中将begin个元素赋给begin-1个元素,之后begin++,实现赋值循环。

顺序表的任意位置插入

有了头插和尾插,我们接下里在任意位置插入,直接上代码。

void SLInsert(SL* psl,int pos,SLDataType x)
{
  assert(psl);
  assert(pos>0&&pos<=psl->size);
  SLCheckCapacity(&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位置之前的数据,所以只需要将0替换为pos即可。之后将x存储到第pos个位置中去,psl所指向的size++即可。

顺序表的任意位置删除

有任意位置插入,就可以有任意位置删除,我们直接看代码。

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

首先,依然是断言,保证pos的合法,之后和头删的操作其实很相似,我们把第pos个位置看成首地址去进行头删即可。

顺序表的查找

我们可能会需要查找顺序表的某个元素,来实现一下

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

直接,遍历之后找到下表就返回i,没有就返回-1。

代码与总结

顺序表可以帮助我们实现一些信息的管理,有助于我们写一些学生信息管理等等,相信大家都能够做出来这样的系统,就不再展示,以后有机会会展示给大家。

最后给大家看一下,鄙人的代码实现,是封装为3个文件的。

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* psl);//初始化顺序表
void SLDestroy(SL* psl);//销毁顺序表
void SLPushBack(SL* psl, SLDataType x);//头插
void SLPushFront(SL* psl, SLDataType x);//尾插
void SLPrint(SL* psl);//打印顺序表
void SLCheckCapacity(SL* psl);//增容
void SLPopBack(SL* psl);//尾删
void SLPopFront(SL* psl);//头删
// 任意下标位置的插入删除
void SLInsert(SL* psl, int pos, SLDataType x);
void SLErase(SL* psl, int pos);

SeqList.c

#define  _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void SLInit(SL* psl)
{
  assert(psl);
  psl->a = NULL;
  psl->size = 0;
  psl->capacity = 0;
}
void SLDestroy(SL* psl)
{
  assert(psl);
  if (psl->a != NULL)
  {
    free(psl->a);
    psl->a = NULL;
    psl->size = 0;
    psl->capacity = 0;
  }
}
void SLPrint(SL* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    printf("%d ", psl->a[i]);
  }
  printf("\n");
}
void SLCheckCapacity(SL* psl)
{
  assert(psl);
  if (psl->size == psl->capacity)
  {
    int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
    SLDataType* tmp = (SLDataType*)realloc(psl->a,sizeof(SLDataType) * newcapacity);
    if (tmp == NULL)
    {
      perror("realloc fail");
      return;
    }
    psl->a = tmp;
    psl->capacity = newcapacity;
  }
}
void SLPushBack(SL* psl, SLDataType x)
{
  assert(psl);
  SLCheckCapacity(psl);
  psl->a[psl->size] = x;
  psl->size++;
}
void SLPushFront(SL* psl, SLDataType x)
{
  assert(psl);
  SLCheckCapacity(psl);
  int end = psl->size-1;
  while (end >= 0)
  {
    psl->a[end+1] = psl->a[end];
    end--;
  }
  psl->a[0] = x;
  psl->size++;
}
void SLPopBack(SL* psl)
{
  assert(psl);
  assert(psl->size > 0);
  psl->size--;
}
void SLPopFront(SL* psl)
{
  assert(psl);
  assert(psl->size > 0);
  int begin = 1;
  while (begin < psl->size)
  {
    psl->a[begin - 1] = psl->a[begin];
    begin++;
  }
  psl->size--;
}
// 任意下标位置的插入删除
void SLInsert(SL* psl, int pos, SLDataType x)
{
  assert(psl);
  assert(pos > 0 && pos <= psl->size);
  SLCheckCapacity(psl);
  int end = psl->size - 1;
  while (end >=pos)
  {
    psl->a[end+1] = psl->a[end];
    end--;
  }
  psl->a[pos] = x;
  psl->size++;
}
void SLErase(SL* psl, int pos)
{
  assert(psl);
  assert(pos > 0 && pos <= psl->size);
  int begin = pos+1;
  while (begin <psl->size)
  {
    psl->a[begin-1] = psl->a[begin];
    begin++;
  }
  psl->size--;
}

还有一个test.c的文件是用来测试顺序表的,大家自行测试即可,谢谢大家的观看!

目录
相关文章
|
6月前
|
JSON Kubernetes 负载均衡
在K8s中,“deployment”的角色和功能
总的来说,Kubernetes中的Deployment就像一位尽职的舞台指挥,默默察看、控制我们的Pods,确保它们在变化的环境中始终保持最佳状态,从而让我们的应用程序可以稳定运行。
165 38
|
9月前
|
缓存 JSON 数据处理
Python进阶:深入理解import机制与importlib的妙用
本文深入解析了Python的`import`机制及其背后的原理,涵盖基本用法、模块缓存、导入搜索路径和导入钩子等内容。通过理解这些机制,开发者可以优化模块加载速度并确保代码的一致性。文章还介绍了`importlib`的强大功能,如动态模块导入、实现插件系统及重新加载模块,展示了如何利用这些特性编写更加灵活和高效的代码。掌握这些知识有助于提升编程技能,充分利用Python的强大功能。
405 4
|
监控 安全 网络安全
状态检测防火墙
【8月更文挑战第17天】
903 3
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
AI在自然语言处理中的突破:从理论到应用
AI在自然语言处理中的突破:从理论到应用
394 17
|
12月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
190 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
12月前
|
机器学习/深度学习 人工智能 数据可视化
|
12月前
|
C语言
C语言数组练习以及场景练习题
C语言数组练习以及场景练习题
259 0
|
数据库
面试准备 数据迁移解决方案
【8月更文挑战第8天】
140 7
|
Rust 安全 程序员
揭秘Rust语言的内存安全秘籍:如何构建坚不可摧的系统级应用?
【8月更文挑战第31天】Rust语言凭借其独特内存安全机制在编程领域脱颖而出,通过所有权、借用与生命周期等概念,在保证高性能的同时避免了缓冲区溢出等常见错误。本文深入探讨Rust的内存安全机制,并通过示例代码展示如何利用这些机制构建高效且可靠的系统。尽管这些机制增加了学习难度,但为软件开发奠定了坚实基础,使Rust成为系统、嵌入式及网络编程的理想选择。随着社区的发展,Rust将在未来软件开发中扮演更重要角色。
352 0