C语言实现顺序表的增删查改

目录

线性表的优缺点:

数据准备:头文件

初始化

柔性报错

硬性报错 - 推荐

 打印

容积判断

头插

实现构图

 尾插

头删

头删实现构图

 尾删

 按位插入

按位插入实现构图

 销毁

 查找

main

练习

移除元素

删除有序数组重复项

合并两个有序数组



线性表的优缺点:

    优点:

               1,物理空间连续,下表可以直接访问;

                2,尾插尾删效率高;

    缺点:

                1,扩容会有一定的性能消耗;

      原因是使用的realloc函数,原地址空间不够,会到新地址重新开辟空间,届时在将原来空间的数据拷贝过来,如果数据多,拷贝就会需要耗费一些性能

                2,头部插入和删除或者中间插入和删除效率低下;

        原因是需要挪动数组,数据量大的话也是相当耗性能的;

何为顺序表:

        物理地址连续的储存单元依次存储数据元素;

        说人话就是:是个数组,但是支持扩容.

数据准备:头文件

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLDatatype; //方便后期修改指针的类型

typedef struct SeqList
{
    SLDatatype* a;       //指向动态数组的指针
    int size;           //数据个数
    int capacity;      //容量
}SL;

初始化

///初始化
void SLInit(SL* ps)
{
    assert(ps);  
    ps->a = NULL;    //指针指向为NULL
    ps->capacity = ps->size = 0;
  //容积\大小设置为0
}

柔性报错

//柔性报错,当出现一些极端值或者非法参数,设置对应条件进行拦截;输出函数基本有自己指定
//项目简单文件少还好,代码多了时间长,柑橘会一脸茫然,甚至怀疑
void checkSize(SL* ps,char* str)
{
    if (ps->size == 0)    //ps->a指针的size为0;
    {
        printf("%s :: ps->size==0",str);
 //输出字符串;
        exit(1);  //直接退出程序
    }
}

硬性报错 - 推荐

assert。满足条件直接打印错误信息(输入的表达式,文件位置,代码行数)

///初始化
void SLInit(SL* ps)
{
    assert(ps);    //当ps为NULL  也就是表达式子为flase的时候。触发
    ps->a = NULL;   
    ps->capacity = ps->size = 0;
}

 打印

///打印
void SLPrint(SL* ps)
{
    assert(ps);
    //checkSize(ps, "SLPrint"); //柔性
    
    //直接型报错,报错的内容为表达式内容
    assert(ps->size >= 0);  //表达式为false 触发    
    for (int i = 0; i < ps->size; ++i)
    {
        printf("%d ", ps->a[i]);
    }
    printf("\n");
}

容积判断

///判断容积大小
void SLCheckCapacity(SL* ps)
{
    assert(ps);
    if (ps->capacity != ps->size)   // 当容积(capacity))和大小(size)相等,就说明需要扩容了
        return;
    SLDatatype newCapacity = ps->capacity == 0 ?  4: ps->capacity * 2;    //第一次size为0,扩容4个;后面一次扩容两倍,
    SLDatatype* tmp = (SLDatatype*)realloc(ps->a, newCapacity*sizeof(SLDatatype)); // realloc第一次使用,等同malloc 
    if (tmp == NULL)   //判断空间是否创建成功,
    {
        perror("realloc :: SL");
        exit(1);
    }
    ps->a = tmp;  //把新的空间赋予结构体指针
    ps->capacity = newCapacity;
  //将容积(capacity)改写
}

头插

///头部追加
void SLPushFront(SL* ps, SLDatatype x)
{
    assert(ps);
    SLCheckCapacity(ps);    //追加检查容积大小能不能放下.
    for (int i = ps->size; i >= 0; --i)
    {
        ps->a[i + 1] = ps->a[i];
    }
    ps->a[0] = x;
    ++ps->size;

    
}

实现构图

 尾插

///尾部追加
void SLPushBack(SL* ps,SLDatatype x)
{
    assert(ps);
    SLCheckCapacity(ps);
    ps->a[ps->size] = x;
    ++ps->size;
}

头删

///头部删除 
void SLPopFront(SL* ps)
{
    assert(ps);
    //checkSize(ps, "SLPopFront"); //柔性
    assert(ps->size >= 0);
    for (int i = 0; i < ps->size; ++i)
    {
        ps->a[i] = ps->a[i + 1];
    }
    --ps->size;

}

头删实现构图

 尾删

///尾部删除 
void SLPopBack(SL* ps)
{
    assert(ps);
    //checkSize(ps, "SLPopBack");   //柔性
    assert(ps->size >= 0);
    if (ps->size>=0) 
    --ps->size;
}

 按位插入

///按位插入
void SLInsert(SL* ps, int pos, SLDatatype x)
{
    assert(ps);     
    assert(pos >= 0 && pos <= ps->size);  //检测pos和ps->size的值为合法
    
    SLCheckCapacity(ps);   
    for (int i =ps->size; i >=  pos; --i)
    {
        ps->a[i + 1] = ps->a[i];
    }
    ps->a[pos] = x;
    ++ps->size;
}

按位插入实现构图

 销毁

///销毁
void SLDestroy(SL* ps)
{
    assert(ps);
    free(ps->a);
    ps->a = NULL;
    ps->size = 0;
    ps->capacity = 0;
}

 查找

///查找
int  SLFind(SL* ps, SLDatatype x)
{
    assert(ps);
    //assert(ps->size >= 0);  //表达式为0 触发
 推荐
    checkSize(ps,"SLFind");     //柔性报错;
    for (int i = 0; i < ps->size - 1; ++i)
    {
        if (x == ps->a[i])
        {
            return i;
        }
    }
    return -1;
}

main

void test4()
{
    SL sl;
    //初始化
    SLInit(&sl);
    SLPushBack(&sl, 5);
    SLPushBack(&sl, 5);
    SLPushBack(&sl, 5);
    SLPushBack(&sl, 5);
    SLPushBack(&sl, 5);
    SLPrint(&sl);

    SLDestroy(&sl);    
    SLPrint(&sl);


    int pos = 0;
    printf("请输入要查找的数:>");
    scanf("%d", &pos);
    printf("%d", SLFind(&sl, pos));
    
}
int main()
{
    test4();
    return 0;
}

练习

移除元素

https://leetcode-cn.com/problems/merge-sorted-array/

删除有序数组重复项

合并两个有序数组

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值