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

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务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的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
存储 算法 C语言
实现顺序表——实践报告
实现顺序表——实践报告
104 0
|
1月前
|
存储 算法
【数据结构】新篇章 -- 顺序表
【数据结构】新篇章 -- 顺序表
15 0
|
3月前
|
Java C++
【C项目】顺序表
【C项目】顺序表
|
6月前
|
C语言
顺序表的实现(迈入数据结构的大门)(2)
顺序表的实现(迈入数据结构的大门)(2)
41 0
|
6月前
顺序表的实现(迈入数据结构的大门)(1)
顺序表的实现(迈入数据结构的大门)(1)
32 0
|
6月前
|
存储 算法 Java
【数据结构与算法】4.自主实现单链表的增删查改
【数据结构与算法】4.自主实现单链表的增删查改
|
6月前
顺序表与链表(双向)优劣势
顺序表与链表(双向)优劣势
49 0
|
存储 搜索推荐
【数据结构】第二站:顺序表
【数据结构】第二站:顺序表
41 0
|
索引
链表问题汇集
链表问题汇集
68 1
|
存储 C语言
【数据结构】线性表之单链表(讲解实现——带动图理解)(2)
单链表 单链表的优点 1.头部和中间插入或删除数据效率高,无需挪动。 2.按照需求申请释放空间,无需担心空间不够用。 单链表的缺点 1.不可以进行下标随机访问。 2.复杂度是O(n) 3.反向遍历困难 单链表是线性表的一种,单链表是链式存储的线性表,不同于单链表,链表在内存空间中不连续,而是由结构体内的next指针下一条数据进行链接🧐