数据结构--顺序表

顺序表

  • 1.概念和结构
  • 2.分类
    • 2.1静态顺序表
    • 2.2动态顺序表
  • 3.动态顺序表代码实现
    • 3.1 顺序表的定义
    • 3.2 顺序表初始化
    • 3.3 顺序表的销毁
    • 3.4 顺序表的插入
    • 3.5 顺序表的删除
    • 3.6 顺序表在指定位置之前插入/删除数据
    • 3.7 顺序表的查找
  • 4. 总结

1.概念和结构

  • 概念
    • 顺序表是线性表1的一种存储方式,它是用一组地址连续的存储单元依次存储线性表中的数据元素。简单来说,就像是把一系列的数据一个挨着一个地存放在一块连续的内存空间中,就像排队一样有顺序。这种存储结构使得顺序表中的元素在逻辑上和物理位置上都是相邻的。
      例如,假设有一个顺序表存储学生的成绩,这些成绩在内存中是连续存放的,通过索引(位置)可以很方便地访问每个成绩。
    • 顺序表底层结构是数组,是对数组的封装,实现常用的增删查找等接口。
    • 顺序表是对数组的包装,在其基础上,增加了增删查找的方法,成为一种数据结构。
  • 结构
    • 顺序表的数据元素存储在一段连续的内存空间中。这意味着如果知道了第一个元素的存储地址和每个元素所占用的空间大小,就可以很容易地计算出其他元素的存储地址。
    • 例如,如果第一个元素的地址是 addr,每个元素占用 size 字节,那么第 n 个元素的地址就是 addr+(n - 1)*size。(与数组的指针相似
    • 顺序表在物理结构上和逻辑结构上都是连续的。

2.分类

  • 2.1静态顺序表

    • 概念:使用定长数组存储元素。
    • 定义:
#define MAX_SIZE 100   // 定义顺序表的最大容量
typedef struct {
    int data[MAX_SIZE];  // 存储数据的数组,假设存储整数
    int length;          // 当前顺序表中元素的实际长度
} StaticSeqList;
静态顺序表缺陷:空间给少了不够⽤,给多了造成空间浪费。
  • 2.2动态顺序表

    • 定义:
typedef struct {
    int *data;           // 指向存储数据的动态分配数组的指针
    int length;          // 当前顺序表中元素的实际长度
    int capacity;        // 顺序表的当前容量
} DynamicSeqList;
优点:可扩容。

对于动态顺序表的结构体 DynamicSeqListdata 是一个指针,用于指向通过动态内存分配得到的数组空间,存储顺序表的数据元素。length 记录实际元素个数,capacity 表示当前顺序表所能容纳的最大元素数量。当需要添加元素而 length 达到 capacity 时,就需要重新分配内存来扩大容量。

3.动态顺序表代码实现

3.1 顺序表的定义

#include
#include
#include
 //----------------------------
 //#define N 100
 //struct seqList
// {
   // int arr[N];
    //int size;//有效数据个数
// };
//静态顺序表
//------------------------------
typedef int SLDataType//方便改变数据类型
struct seqList
{
       SLDataType *arr;
       int size;
       int capacity;
}SL;

3.2 顺序表初始化

 //初始化
void SLInit(SL *ps)//必须用指针类型传参
{
   ps->arr=NULL;
   ps->size=0;
   ps->capacity=0;
}

3.3 顺序表的销毁

void SLDestory(SL*ps)
{
    if(ps->arr)
    {
       free(ps->arr);
    }
    ps->arr=NULL;
    ps->size=ps->capacity=0;
}
        

3.4 顺序表的插入

  • 尾插
   void SLPushBack(SL* ps,SLDataType x)
   {
     assert(ps);
     if(ps->capacity==ps->size)//判断是否有空间
     {
       int newCapacity = ps->capacity==0?4:2*ps->capacity;//三目表达式
       SLDataType*tmp =(SLDataType*)realloc(ps->arr,newCapacity*2*sizeof(SLDataType));
        //增容通常是成倍数增加,一般是2~3倍。
       if(tmp==NULL)
       {
           perror("realloc fail!");
           exit(1);//直接退出程序
       }
       ps->arr=tmp;
       ps->capacity=newCapacity;
     }
       ps->arr[ps->size++]=x;
   }    
  • 头插
void SLPushFront(SL*ps,SLDatatype)
{
    if(ps->size==ps->capacity)
    {
        int newCapacity = ps->capacity==0?4:2*ps->capacity;//三目表达式
       SLDataType*tmp =(SLDataType*)realloc(ps->arr,newCapacity*2*sizeof(SLDataType));
        //增容通常是成倍数增加,一般是2~3倍。
       if(tmp==NULL)
       {
           perror("realloc fail!");
           exit(1);//直接退出程序
       }
       ps->arr=tmp;
       ps->capacity=newCapacity;
     }
    // 顺序表所有数据往后挪一位
    forint i=ps->size;i>0;i--)
    {
       ps->arr[i]=ps->arr[i-1];
    }
   ps->arr[0]=x;
   ps->size++;
}       

3.5 顺序表的删除

  • 尾删
void SLPopBack(SL *ps)
{
    assert(ps);
    assert(ps->size);//判断顺序表不为空
    //ps->arr[ps->size-1]=-1;可有可无
    ps->size--;
}
  • 头删
 void SLPopFront(SL *ps)
 {
     assert(ps);
     assert(ps->size);
     //
     for(int i=0;i<ps->size-1;i++)
     {
        ps->arr[i]=ps->arr[i+1];
     }
     ps->size--;
 }

3.6 顺序表在指定位置之前插入/删除数据

  • 指定位置之前插入(综合了头插和尾插)
 void SLInsert(SL *ps,int pos,SLDataType x)
 {
     assert(ps);
     assert(pos> = 0&&pos <= ps->size); 
      if(ps->size==ps->capacity)
    {
        int newCapacity = ps->capacity==0?4:2*ps->capacity;//三目表达式
       SLDataType*tmp =(SLDataType*)realloc(ps->arr,newCapacity*2*sizeof(SLDataType));
        //增容通常是成倍数增加,一般是2~3倍。
       if(tmp==NULL)
       {
           perror("realloc fail!");
           exit(1);//直接退出程序
       }
       ps->arr=tmp;
       ps->capacity=newCapacity;
     }
     for(int i=ps->size;i>pos;i--)
     {
        ps->arr[i]=ps->arr[i-1];
     }
     ps->arr[pos]=x;
     ps->size++;   
          
 }     
  • 指定位置之前删除数据
void SLErase (SL*ps ,int pos)
{ 
   assert(ps);
   assert(pos>=0 && pos<ps->size);
   for(int i=pos;i<ps->size-1;i++)
   {
       ps->arr[i]=ps->arr[i+1];
   }   
   ps->size--;
}   

3.7 顺序表的查找

int SLFind (SL* ps,SLDataType x)
{
    assert(ps);
    for(int  i=0;i< ps->size;i++)
    {
         if(ps->arr[i]==x)
         {
            return i;//找到了
         }
     return -1;
}    
             

4. 总结

顺序表的插入、删除、查找的原理与数组相同。但注意,开始时要进行初始化,结束时要进行销毁,同时通过assert进行断言检查判断是否有空间来提高代码健壮性。


  1. 线性表(linear list)是n个具有相同特性的数据元素的有限序列。
    线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串…
    线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性表在物理上存储时,通常以数组链式结构的形式存储。 ↩︎

你可能感兴趣的:(数据结构,数据结构,算法)