【顺序表】大数据,请把它推给还不会顺序表的人(下)

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 【顺序表】大数据,请把它推给还不会顺序表的人

5.顺序表的尾插

顺序表中对于初学者最为头疼的是特殊情况的考虑和元素的后移前移操作,但是只要动动脑筋,就能运用自如,切忌死记硬背!

插入删除移动问题的见解:

1.

7d0be9cf92f348eaa8f53928255a730c.png

2.

对于插入数据,我们应该从数组尾处开始后移;对于删除数据,我们应该从删除端开始前移

(原因是从另一头移动会造成数据的覆盖)

类比:尾插就是食堂打饭时老老实实在最后一个人的位置后面排着队,并且干饭人的队伍又多了一名成员罢了.

void SeqListPushBack(SeqList* pq, SeqDataType x)
{
  assert(pq);
  SeqCheckCapacity(pq);
  pq->a[pq->size] = x;
  pq->size++;
}

027b620a76f34a86bb2895d316ee18b1.png

6.顺序表的头插

类比:在食堂打饭的时候,你直接插队插到第一个位置去了,就是头插,那么你占了第一个位置,原来的人就必须得全部后移一个位置啦(哈哈)🤣

void SeqListPushFront(SeqList* pq, SeqDataType x)
{
  assert(pq);
  SeqCheckCapacity(pq);
  int end = pq->size - 1;
  while (end >= 0)
  {
    pq->a[end + 1] = pq->a[end];
    --end;
  }
  pq->a[0] = x;
  pq->size++;
}

6a926c27049b4ced9ee508b2f5d7ebc8.png

7.顺序表的尾删

类比:排队打饭时你突然发现阿姨颠勺颠的厉害,不想在这个窗口排队了

void SeqListPopBack(SeqList* pq)
{
  assert(pq);
  assert(pq->size > 0);
  --pq->size;
}

8.顺序表的头删

类比:你不文明的头插行为被阿姨发现了,在谩骂声下,你不得不离开队伍第一的位置,其他人又可以前进一个位置了

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

de02e227b3a34df383c4318031eaf14a.png

9.顺序表的按值查找

类比:你想找队伍里的小明同学,于是你从队头走到队尾,挨个匹配每个人是否是小明,找到就不找了.

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

10.顺序表的任意位置插入

类比:又是插队!不过这次你是在下标为pos的位置的前一位插入,这就要从插入的位置到最后一位均后退一位才能行(在数组下标为pos的位置前插入一个e元素)

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

16ea6b7c74b04dd19e0b69c9343eaad2.png

11.顺序表的任意位置删除

类比:不文明的行为当然不能容忍,这次你又被踢出去了(删除数组下标为pos的元素)

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

8ff091ba7bd1448cae372aefa5d0e153.png

上面有很多步骤都是可以复用的,例如头插就是在第一个元素前插入一个元素,尾插就是在最后一个元素后插入一个元素等等,快去找找看看吧!

下面来实战一下吧:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int ElemType;
typedef struct SeqList
{
  ElemType* a;
  int size;
  int capacity;
}SeqList;
void InitSeqList(SeqList* ps)
{
  ps->a = (ElemType*)malloc(sizeof(ElemType) * 4);
  if (ps->a == NULL)
  {
    printf("malloc fail\n");
    exit(-1);
  }
  ps->size = 0;
  ps->capacity = 4;
}
void CheckCapacity(SeqList* ps)
{
  if (ps->size == ps->capacity)
  {
    int newcapacity = 2 * ps->capacity;
    ElemType* temp = realloc(ps->a, sizeof(ElemType) * newcapacity);
    if (temp == NULL)
    {
      printf("realloc fail\n");
      exit(-1);
    }
    else
    {
      ps->capacity = newcapacity;
      ps->a = temp;
    }
  }
}
void SeqListPushBack(SeqList* ps, ElemType e)
{
  CheckCapacity(ps);
  ps->a[ps->size] = e;
  ps->size++;
}
void PrintSeqList(SeqList* ps)
{
  printf("顺序表的打印:  ");
  for (int i = 0; i < ps->size; i++)
  {
    printf("%d\t", ps->a[i]);
  }
}
void SeqListInsert(SeqList* ps, int j, ElemType e)
{
  assert(j >= 0 && j <= ps->size);
  CheckCapacity(&ps);
  for (int i = ps->size - 1; i >= j - 1; i--)
  {
    ps->a[i+1] = ps->a[i];
  }
  ps->a[j - 1] = e;
  ps->size++;
}
void SeqListDelete(SeqList* ps, int j)
{
  for (int i = j; i <= ps->size - 1; i++)
  {
    ps->a[i - 1] = ps->a[i];
  }
  ps->size--;
}
int FindSeqList(SeqList* ps, ElemType e)
{
  for (int i = 0; i < ps->size; i++)
  {
    if (e == ps->a[i])
    {
      return i + 1;
    }
  }
  return 0;
}
ElemType GetSeqList(SeqList* ps, int j)
{
  assert(j >= 1 && j <= ps->size);
  return ps->a[j - 1];
}
void SeqListClear(SeqList* ps)
{
  ps->a = NULL;
  ps->size = ps->capacity = 0;
}
void SeqListDestory(SeqList* ps)
{
  free(ps->a);
  ps->a = NULL;
  ps->size = ps->capacity = 0;
}
int main()
{
  printf("宋永红的线性表(1)作业:\n");
  SeqList pq;
  //顺序表的初始化
  InitSeqList(&pq);
  //在顺序表的尾上插入数据
  SeqListPushBack(&pq, 1);
  SeqListPushBack(&pq, 2);
  SeqListPushBack(&pq, 3);
  SeqListPushBack(&pq, 4);
  //打印顺序表
    PrintSeqList(&pq);
  printf("\n");
  //删除第N个元素
  int n = 3;
  SeqListDelete(&pq, n);
  printf("删除第%d个数据后",n);
  PrintSeqList(&pq);
  printf("\n");
  //在第n个位置前插入一个元素
  SeqListInsert(&pq, 2, 100);
  printf("在第2个位置插入100这个数据后");
  PrintSeqList(&pq);
  printf("\n");
  //查找第n个元素,存在返回其位序,找不到返回0
  int findNums = 100;
  int ret=FindSeqList(&pq, findNums);
  if (ret == 0)
  {
    printf("要找的%d不存在\n", findNums);
  }
  else
  {
    printf("%d存在,位序是%d\n", findNums, ret);
  }
  //获取第n个元素
  ElemType x = GetSeqList(&pq, 2);
  printf("顺序表第2个位置的元素是%d\n", x);
  printf("\n");
  //清空
  SeqListClear(&pq);
  //销毁
  SeqListDestory(&pq);
}


打印结果:

b974c99fdfc943c5b7b5d131db456802.png

为什么有扩容没有缩容?


realloc可以达到缩容的目的,但是是开辟了一块新空间来存放旧空间里的内容,这个步骤是需要消耗时间的,所以缩容的话就相当于是用时间换空间,如果不缩容,就相当于是用空间换时间,第一局:平局


但是第二局:不缩容还有一个好处就是在后面又想插入数据的时候,可以不用再扩容,减少扩容消耗的时间,同时内存对于空间还是比较慷慨的。


所以综合来看没有缩容,但是扩容肯定是必须的



相关实践学习
基于MaxCompute的热门话题分析
Apsara Clouder大数据专项技能认证配套课程:基于MaxCompute的热门话题分析
目录
相关文章
|
数据采集
PCIE版本CAN数据采集卡计算机启动无法正常工作
PCIE版本CAN数据采集卡计算机启动无法正常工作
710 0
PCIE版本CAN数据采集卡计算机启动无法正常工作
|
5天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
16天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1317 5
|
3天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
15天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1372 87
|
3天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
4天前
|
弹性计算 安全 数据安全/隐私保护
2025年阿里云域名备案流程(新手图文详细流程)
本文图文详解阿里云账号注册、服务器租赁、域名购买及备案全流程,涵盖企业实名认证、信息模板创建、域名备案提交与管局审核等关键步骤,助您快速完成网站上线前的准备工作。
211 82
2025年阿里云域名备案流程(新手图文详细流程)