顺序表

顺序表是一种线性结构,通常用数组实现。动态顺序表通过动态开辟数组存储,比静态顺序表更具灵活性。本文将探讨动态顺序表的初始化、销毁、容量检查等操作,并介绍如何进行插入、删除和查找等基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顺序表

概念:顺序表是用一段连续物理地址依次存储数据结构元素的线性结构,一般用数组来存储,在数组上进行增删查改。

顺序表分类:

  1. 静态顺序表:使用定长数组存储
  2. 动态顺序表:使用动态开辟的数组存储
//静态顺序表
#define N 5
typedef int SLDataType;
typedef struct SeqList
{
    SLdataType array[N];// 定长数组
    size_t size;       //有效数据个数
}SeqList;

在这里插入图片描述静态顺序表

//动态顺序表
typedef int SLDataType;
typedef struct SeqList
{
    SLDataType* array;//指向动态开辟的数组的指针
    size_t size;      //有效数据的个数
    size_t capacity;  //容量空间的大小
}SeqList;

在这里插入图片描述

静态顺序表只适用于存储数据量已知的场景。定长数组的N过大导致空间浪费或者N过小导致内存不够,所以静态顺序表在实际中局限性比较大。

所以,动态顺序表动态分配内存的性质,相比静态顺序表更合理更实用一些。

以下的借口实现我们都默认使用动态顺序表

顺序表初始化

//考虑容量为0,容量不为0的情况
void SeqListInit(SeqList* psl, size_t capacity)
{
    assert(psl);//当psl为空时终止程序
    if(capacity==0)
    {
        psl->array=NULL;
        psl->size=0;
        psl->capacity==0;
    }
    else{
        psl->capacity=capacity;
        psl->size=0;
        psl->array=(SLDataType*)malloc(sizeof(SLDataType)*capacity);//为数组开辟空间
    }
}

顺序表销毁

void SeqListDestory(SeqList* psl)
{
    assert(psl);
    //释放数组空间
    free(psl->array);
    psl->array=NULL;
    //将size和capacity都置为0
    psl->size=0;
    psl->capacity=0;
}

检查容量

void Checkcapacity(SeqList* psl)
{
    assert(psl);
    //当size和容量相等时,说明该增容了
    if(psl->size == psl->capacity)
    {
        //定义一个指针变量tmp指向新空间
        STDataType* tmp;
        if(psl->capacity==0)
        {
            psl->capacity=2;
        }
        tmp = realloc(psl->array, psl->capacity*2*sizeof(STDataType));
        assert(tmp);
        psl->array=tmp;
        psl->capacity *=2;
    }
}

这里补充一下realloc的用法:

void* realloc(void* ptr, size_t size);
重新分配内存块
更改ptr指向的内存块的大小。

该函数可以将存储块移动到新位置(其地址由该函数返回)。

即使存储块被移动到一个新位置,存储块的内容也会保留到新大小和旧大小中较小的一个。如果新的大小较大,则新分配的部分的值是不确定的。

如果ptr是空指针,该函数的行为就像malloc一样,分配一个新的大小字节块,并返回一个指向其开头的指针。

尾插数据

void SeqListPushBack(SeqList* psl, STDataType x)
{
    assert(psl);
    Checkcapacity(psl);//检查容量是否足够,防止数组越界
    psl->array[psl->size]=x;
    psl->size++;
}

尾删数据

void SeqListPopback(SeqList* psl)
{
    assert(psl);
    if(psl->size>0)//当有效数据个数大于0时,才可以删除数据
    {
        psl->size--;
    }
}

头删数据

void SeqListPopFront(SeqList* psl)
{
    assert(psl);
    if(psl->size > 0)
    {
        int start = 0;
        while(start < (psl->size-1))//有效数据总数减一
        psl->_array[start]=psl->[start+1];//数据依次向前挪动一位
        ++start;
    }
    psl->size--;
}

某个位置插入数据

void SeqListInsert(SeqList* psl, size_t pos, STDataType x)
{
    int end;
    assert(psl && pos<=(psl->size));//添加数据,有可能添加在末尾,所以pos可能等于size
    Checkcapacity(psl);
    end=psl->size-1;
    while( end >= (int)pos)
    {
        psl->array[end+1]=psl->array[end];//从最后一个位置往前,依次向后挪,空出pos
        --end;
    }
    psl->array[pos]=x;
    psl->size++;
}

查找某个元素

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

删除某个值

void SeqListErase(SeqList* psl, size_t pos)
{
    int start;
    assert(psl &&start < (psl->size));//因为是删除数据,start是下标,不可能等于size
    start=pos;
    while(start<=(psl->size-1))//与insert原理相似
    {
        psl->array[start]=psl->array[start+1];
        start++;
    }
    psl->size--;
}

删除某个位置

void SeqListRemove(SeqList* psl, SLDataType x)
{
    int pos;
    assert(psl);
    pos = SeqListFind(psl,x);
    if(pos != -1)
    {
        SeqListErase(psl,pos);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值