借助三个文件: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;
}