数据结构——lesson2线性表和顺序表

简介: 数据结构——lesson2线性表和顺序表

前言

在学习顺序表之前我们要了解什么是线性表?

1.线性表(linear list)是n个具有相同特性数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

2.线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

一、顺序表是什么?

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

顺序表一般可以分为:

1. 静态顺序表:使用定长数组存储元素

//顺序表的静态存储
#define N 7
typedef int SLDataType;//防止数组类型改变时麻烦
 
typedef struct SeqList
{
 SLDataType arry[N];//定长数组
 size_t size;//有效数据个数
 
}SeqList;

2. 动态顺序表:使用动态开辟的数组存储。

//顺序表的动态存储
typedef struct SeqList
{
  SLDataType* arry;//指向动态开辟的数组
  size_t size;//有效数据个数
  size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致 N 定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用 动态顺序表 ,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

二、接口实现

1.动态顺序表存储

:相较于静态顺序表动态顺序表arry表示的指针数据,不再是定长数组,从而可以使用mallo,realloc函数开辟动态内存空间,此外还增加了capacity变量来记录容量大小

typedef struct SeqList
{
  SLDataType* arry;//指向动态开辟的数组
  size_t size;//有效数据个数
  size_t capacity;//容量空间的大小
}SeqList;//空间不够则增容

①SLDataType:其实是int被typedef的

typedef int SLDataType;//防止数组类型改变时麻烦

②size_t:无符号位的整型

2.基本增删查改接口

(1)初始化顺序表

:(1)asert断言防止传入指针为空;

      (2)使用malloc函数给数组开4个SLDataType(typedef为int,避免修改数据的麻烦)大小的空间;

void SeqListInit(SeqList* psl)//顺序表初始化
{
  assert(psl);//asert断言防止传入指针为空
  psl->arry = (SLDataType*)malloc(sizeof(SLDataType) * 4);//给数组开4个SLDataType大小的空间
  if (psl == NULL)
  {
    perror("malloc fail");//如果开辟没成功则返回错误
    return;
  }
  psl->size = 0;
  psl->capacity = 4;
}

(2)顺序表摧毁

:使用动态内存函数(malloc、realloc等函数)后记得要用free释放空间;

void SeqListDestory(SeqList* psl)//顺序表销毁
{
  assert(psl);//assert断言
  free(psl->arry);//使用动态内存函数后记得要用free释放空间
  psl->arry = NULL;//指针置空
  psl->capacity = 0;
  psl->size = 0;
}

(3)检查空间

:①如果空间满了使用realloc函数来增加空间;

       ②需要人为的将capacity增加到相应的容量(只是内存容量增加了,我们要将capacity与内存链接需要自己动手);

void CheckCapacity(SeqList* psl)
{
  assert(psl);//断言
  if (psl->size == psl->capacity)//判断空间是否满了
  {
    SLDataType* tmp = realloc(psl->arry, sizeof(SLDataType) * 2 * (psl->capacity));
        //增容每次扩展为上一次的2倍
    if (tmp == NULL)//判断是否开辟成功
    {
      perror("realloc fail");
      return;
    }
    psl->arry = tmp;
    psl->capacity *= 2;//开辟成功指示容量的capacity要相应的增加
  }
}

(4)顺序表打印

for循环逐一打印即可;

void SeqListPrint(SeqList* psl)
{
  assert(psl);
  for (int i = 0; i < psl->size; i++)
  {
    printf("%d ", psl->arry[i]);
  }
  printf("\n");
}

(5)顺序表尾插

:①尾插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

       ②相应元素加进去后,顺序表指向有效数据个数(size)要增加(类似于增加容量时capacity也要增加);

       ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListInsert函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size的地方插入x;

void SeqListPushBack(SeqList* psl, SLDataType x)
{
  assert(psl);//断言
  CheckCapacity(psl);//检查容量
  psl->arry[psl->size] = x;
  psl->size++;//顺序表个数要相应增加
  //SeqListInsert(psl,ps->size,x);//在特定位置插入元素x
}

(6)顺序表尾删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

       ②因为顺序表是通过数组下标访问,所以只要将最大的下标减一即可,这样就访问不到最后的元素了,可以看成删掉了一个元素;

       ③后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为size-1的地方删除;

void SeqListPopBack(SeqList* psl)
{
  assert(psl);//断言
  if (psl->size == 0)//判断顺序表是否有元素
  {
    return;//没有直接返回
  }
  psl->size--;//顺序表个数-1
  //SeqListErase(ps,ps->size-1);//在顺序表末尾删除元素
}

(7)顺序表头插

:①头插数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

       ②头插数据之前的数据下标要整体+1;顺序表个数也要+1;

       ③后续等学习了在特定位置(pos)插入相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的首端也就是下标为0的地方插入x;

void SeqListPushFront(SeqList* psl, SLDataType x)//顺序表头插
{
  assert(psl);
  CheckCapacity(psl);//检查容量
  
  for (int i = psl->size-1; i >= 0; i--)//顺序表整体向后移
  {
    psl->arry[i + 1] = psl->arry[i];
  }
  psl->size++; //顺序表个数+1
  psl->arry[0] = x;
  //SeqListInsert(ps,0,x);//在下标为0的位置插入x
}

(8)顺序表头删

:①要先判断顺序表中是否储存了元素,如果没有则没有继续的必要;

       ②删除第一个元素,顺序表下标都要-1;

       ③顺序表元素个数(size)也要-1;

       ④后续等学习了在特定位置(pos)删除相应元素后即可使用SeqListErase函数,能大大提高代码的利用率,此时应该在顺序表的尾端也就是下标为0的地方删除;

void SeqListPopFront(SeqList* psl)//顺序表头删
{
  assert(psl);//断言
  if (psl->size == 0)//判断是否为空
    return;
  for (int i = 1; i < psl->size; i++)//顺序表数据整体都要前移
  {
    psl->arry[i - 1] = psl->arry[i];
  }
  psl->size--;//顺序表个数-1
  //SeqListErase(ps,0);//在下标为0位置删除
}

(9)顺序表在pos位置插入x

:①在特定位置插入数据也是增加数据所以要用检查容量函数(CheckCapacity)检查容量;

       ②判断插入下标pos是否合理(要小于size);

       ③插入pos位置的数据,其后的数据下标都要整体+1;

       ④顺序表元素个数(size)要+1;

void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)//在pos位置插入x
{
  assert(psl);//断言
  assert(pos <= psl->size);//判断pos是否小于最大的下标
  CheckCapacity(psl);//检查容量
  for (int i = psl->size - 1; i >= pos; i--)//下标在pos之后的要整体+1
  {
    psl->arry[i + 1] = psl->arry[i];
  }
  psl->arry[pos] = x;//将x插入pos位置
  psl->size++;//顺序表元素个数+1
}

(10)顺序表在pos位置删除x

:①删除元素size要-1;

       ②在pos位置删除元素,pos之后的下标都要-1;

void SeqListErase(SeqList* psl, size_t pos)//在特定位置删除元素
{
  assert(psl);//断言
  for (int i = pos + 1; i < psl->size; i++)//pos之后下标-1
  {
    psl->arry[i - 1] = psl->arry[i];
  }
  psl->size--;//顺序表元素个数-1;
}

(11)顺序表查找

int SeqListFind(SeqList* psl, SLDataType x)//顺序表查找
{
  assert(psl);//断言
  if (psl->size == 0)//判断是否为空
    return -1;
  for (int i = 0; i < psl->size; i++)//循环逐一查找
  {
    if (psl->arry[i] == x)
    {
      printf("%d\n", i);
      return i;//找到了返回下标
    }
  }
  printf("没找到\n");
    return -1
}

3.代码运行结果如下:

以上就是顺序表的所以内容啦,欢迎三连回访,有问题可以后台私信我或者打在评论区哦~

相关文章
|
1月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
49 2
|
18天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
18天前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
50 3
|
18天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
30 6
|
1月前
|
存储 安全 Java
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
【用Java学习数据结构系列】探索顺序表和链表的无尽秘密(附带练习唔)pro
23 3
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
19 2
|
18天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 算法 索引
【数据结构】——顺序表
【数据结构】——顺序表
|
1月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
22 1