C语言实现动态顺序表

目录

概念

顺序表的定义

顺序表的初始化

顺序表的尾插

顺序表的增容

顺序表的尾删 

顺序表的头插

顺序表的头删 

顺序表的查找 

在指定位置插入 

在指定位置的删除

顺序表的销毁

顺序表的打印 

 顺序表的优缺点


概念

在写顺序表之前,我们需要了解什么是顺序表,其实顺序表就是数组,只不过我们在数据结构上习惯上称之为顺序表,所以写出一个顺序表是非常简单的,就是对数组进行操作,只不过封装了。

我们的通讯录就是用顺序表去实现的,所以如果写过通讯录的话,写顺序表也不是什么难事,通讯录代码详见C语言 顺序表实现通讯录【完全版】 含文件版本fwrite、fread和fscanf和fprintf的使用_努力敲代码的小王的博客-CSDN博客

顺序表的功能:

1.顺序表的尾插

2.顺序表的尾删

3.顺序表的头插

4.顺序表的头删

5.顺序表的查找

6.在指定位置插入

7.在指定位置删除

顺序表的定义

typedef int SDataType;
typedef struct SeqList
{
    SDataType* arr;
    int sz; //记录当前的个数
    int capacity; //容量
}SL;

顺序表的初始化

定义好以后我们需要进行初始化,把里面的数据置为空

void Init_SeqList(SL* ps)
{
    ps->arr=NULL;
    ps->sz=ps->capacity=0;
}

顺序表的尾插

把顺序表想成数组,找到数组中当前的个数,然后把数据插入进去,然后个数+1 

void SeqListPushBack(SL* ps,SDataType x)
{
    //普通版
    assert(ps);
    checkcapacity(ps);
    ps->arr[ps->sz]=x;
    ps->sz++;

    //优化版
    // SeqListInsert(ps,ps->sz,x);
}

顺序表的增容

不过在插入之前,我们需要检查容量,然后如果顺序表当前的个数等于容量,我们就需要扩容

void checkcapacity(SL* ps)
{
    if(ps->sz==ps->capacity)
    {
        int newcapacity=ps->capacity==0?4:ps->capacity*2;
        SDataType* tmp=(SDataType*)realloc(ps->arr,sizeof(SDataType)*newcapacity);
        if(tmp==NULL)
        {
            perror("malloc fail:");
            exit(-1);
        }
        ps->arr=tmp;
        ps->capacity=newcapacity;
    }
}

顺序表的尾删 

实现尾删非常简单,只需要把记录顺序表个数的变量sz-1就可以了

void SeqListPopBack(SL* ps)
{
    //普通版
    assert(ps->sz>0);
    ps->sz--;

    //优化版
    // SeqListErase(ps,ps->sz);
}

顺序表的头插

想要在头部插入数据,我们就需要把第一个位置空出来,和在数组头部插入数据是一摸一样的

void SeqListPushFront(SL* ps,SDataType x)
{
    // 普通版
    assert(ps);
    checkcapacity(ps);
    int i=0;
    for(i=ps->sz;i>0;i--)
    {
        ps->arr[i]=ps->arr[i-1];
    }
    ps->arr[i]=x;
    ps->sz++;

    //优化版
    // SeqListInsert(ps,0,x);
}

顺序表的头删 

想要在头部进行删除,就需要把后面的数据往前挪动,这样就实现了顺序表的头删

void SeqListPopFront(SL* ps)
{
    //普通版
    assert(ps);
    assert(ps->sz>0);
    int i=0;
    for(i=0;i<ps->sz-1;i++)
    {
        ps->arr[i]=ps->arr[i+1];
    }
    ps->sz--;

    //优化版
    // SeqListErase(ps,0);
}

顺序表的查找 

查找数据时,我们只需要从头到尾遍历一遍顺序表,若是找到我们便会返回下标

int SeqListFind(SL* ps,SDataType x)
{
    int i=0;
    for(i=0;i<ps->sz;i++)
    {
        if(ps->arr[i]==x)
        {
            return i;
        }
    }
    return -1;
}

在指定位置插入 

首先我们需要把指定位置的数据全部往后移,然后就会把需要插入数据的位置空出来

void SeqListInsert(SL* ps,int pos,SDataType x)
{
    assert(ps);
    checkcapacity(ps);
    int i=0;
    for(i=ps->sz;i>pos;i--)
    {
        ps->arr[i]=ps->arr[i-1];
    }
    ps->arr[i]=x;
    ps->sz++;
}

在指定位置的删除

把指定位置后面的数据全部往前移该功能就完成了

写完指定插入和删除就可以优化我们的头插和尾插了,可以回过头来去看我的优化版本

void SeqListErase(SL* ps ,int pos)
{
    int i=0;
    assert(ps);
    assert(ps->sz>0);
    for(i=pos;i<ps->sz-1;i++)
    {
        ps->arr[i]=ps->arr[i+1];
    }
    ps->sz--;
}

顺序表的销毁

我们需要把顺序表内的指针置为空就可以了,因为顺序表是一块连续的空间,如果是链表则序表把每一个节点都销毁掉,然后把当前个数和容量也都置为空

void SeqListDestroy(SL* ps)
{
    assert(ps);
    if(ps->arr)
    {
        free(ps->arr);
        ps->sz=ps->capacity=0;
    }
}

顺序表的打印 

void SeqListPrint(SL* ps)
{
    int i=0;
    for(i=0;i<ps->sz;i++)
    {
        printf("%d ",ps->arr[i]);
    }
    printf("\n");
}

 顺序表的优缺点

优点:(1)尾插尾删效率高   (2)支持随机访问

缺点:(1)头插头删效率低   (2)连续的物理空间,空间不够需要增容(增容有一定程度的消耗,为了避免频繁增容,又可能会导致空间浪费)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值