顺序表的实现及增删查改

借助三个文件:SeqList.h        SeqList.c        test.c

SeqList.h:声明头文件、函数声明、结构体、全局变量等创建

#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* psl);
void SLDestroy(SL* psl);

void SLPrint(SL* psl);
void SLPushBack(SL* psl, SLDatatype x);
void SLPushFront(SL* psl, SLDatatype x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);

void SLInsert(SL* psl, int pos, SLDatatype x);
void SLErase(SL* psl, int pos);

// 找到返回下标,没有找到返回-1
int SLFind(SL* psl, SLDatatype x);
void SLModify(SL* psl, int pos, SLDatatype x);


 

 SeqList.c :对.h文件中生命的函数的实现

#include"SeqList.h"


void SLInit(SL* psl)
{
    assert(psl);
    psl->a = (SLDatatype*)malloc(sizeof(SLDatatype)*4);         //需要free
    if (psl->a == NULL)
    {
        perror("malloc fail");
        return;
    }

    psl->capacity = 4;    //容量
            //数据个数
    psl->size = 0;
}

void SLDestroy(SL* psl)
{
    assert(psl);
    free(psl->a);
    psl->a = NULL;
    psl->size = 0;
    psl->capacity = 0;
}

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

void SLCheckCapacity(SL* psl)
{
    assert(psl);

    if (psl->size == psl->capacity)    //元素个数等于容量
    {
        SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);            //类型 * 2倍容量
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }

        psl->a = tmp;
        psl->capacity *= 2;
    }
}
 

void SLPushBack(SL* psl, SLDatatype x)
{
    assert(psl);

      SLInsert(psl, psl->size, x);
}

void SLPushFront(SL* psl, SLDatatype x)
{
    assert(psl);        //首先要确定不是空指针
    SLInsert(psl, 0, x);        //头插函数直接调洪SLInsert函数(插入位置下标是0)                //尾插同理
}


void SLPopBack(SL* psl)
{
    assert(psl);

    SLErase(psl, psl->size-1);     
}

void SLPopFront(SL* psl)
{
    assert(psl);

    SLErase(psl, 0);
}


//插入用end

void SLInsert(SL* psl, int pos, SLDatatype x)        //SeqList 缩写为SL
{
    assert(psl);
    //assert(0 <= pos <= psl->size);
    assert(0 <= pos &&  pos<= psl->size);

    SLCheckCapacity(psl);

    int end = psl->size - 1;   //末下标
    while (end >= pos)  //将需要插入的位置之后的数据全部后移  
    {
        psl->a[end + 1] = psl->a[end];    //从后往前移动    (end + 1,并不会越界,(SLCheckCapacity(psl) 该语句已经完成扩容)
        --end;
    }

    psl->a[pos] = x;        //在pos处插入 , pos及以后的所有原来的数据后移
    psl->size++;
}

//删除用start

void SLErase(SL* psl, int pos)
{
    assert(psl);
    assert(0 <= pos && pos < psl->size);        //断言!
    //assert(psl->size > 0);

    int start = pos + 1;
    while (start < psl->size)
    {
        psl->a[start - 1] = psl->a[start];
        ++start;
    }

    psl->size--;
}

int SLFind(SL* psl, SLDatatype x)
{
    assert(psl);

    for (int i = 0; i < psl->size; i++)
    {
        if (psl->a[i] == x)
        {
            return i;
        }
    }

    return -1;
}

void SLModify(SL* psl, int pos, SLDatatype x)    //修改
{
    assert(psl);

    assert(0 <= pos && pos < psl->size);

    psl->a[pos] = x;    //psl直接找到元素并修改
}

test.c:用于测试(一般不建议先写控制台,优先利用test函数去测试)


void menu()
{
    printf("***************************************\n");
    printf("1、尾插数据  2、尾删数据\n");
    printf("3、头插数据  4、头删数据\n");
    printf("5、打印数据  -1、退出\n");
    printf("***************************************\n");
}

int main()
{
    int option = 0;
    SL s;
    SLInit(&s);
    while (option != -1)
    {
        menu();
        printf("请输入你的操作:>");
        scanf("%d", &option);
        if (option == 1)
        {
                      int n = 0;
            printf("请输入要尾插的数据个数,再依次输入要插入的数据:");
            scanf("%d", &n);    //个数

            int x = 0;
            while (n > 0)
            {
                scanf("%d", &x);    //当一次输入多个数据的时候,只要 < n个,就能依次执行下面的任务
                SLPushBack(&s, x);
                n--;
            }
        }
        else if (option == 5)
        {
            SLPrint(&s);
        }
        else if (option == -1)
        {
            break;
        }
        else
        {
            printf("无此选项,请重新输入\n");
        }
    }

    SLDestroy(&s);                //需要销毁!

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值