seqlist.h
#pragma once
typedef int SLDataType;
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct SeqList
{
SLDataType* a;
int size; // 有效数据个数
int capacity; // 空间容量
}SL;
//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头部插?删除 / 尾部插?删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//指定位置之前插?/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
试着自己根据上方头文件,写一篇属于自己的顺序表吧!!!
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"seqlist.h"
//typedef int SLdataTapy;
//#define N 10
//
//typedef struct seqlist {
// SLdataTapy arr[N];//定长数组
// int size;//有效数组个数
//}SL;
//typedef int SLdataTapy;
//
//typedef struct seqlist {
// SLdataTapy* a;//用来开辟动态内存
// int size;//有效数组个数
// int capacity;//剩余容量;判断是否需要新添加内存
//}SL;
//初始化和销毁
void SLInit(SL* ps) {
ps->a = NULL;
ps->size = ps->capacity = 0;
}
void SLDestroy(SL* ps) {
if (ps->a) {//判断数组中是否为空
free(ps->a);//因为需要使用malloc,所以需要注意释放内存
}
ps->a = NULL;
ps->size = ps->capacity = 0;
}
//扩容
void SLCheckCapacity(SL* ps) {
//先要判断内存够不够
if (ps->size == ps->capacity) {
//使用malloc relloc celloc
int newcappacity = ps->capacity == 0 ? 4 :ps->capacity*2;//一般增容原来内存的二到三倍;
SLDataType*tmp = (SLDataType*)relloc(ps->a,newcappacity * sizeof(SLDataType));
//注:这里没有直接使用ps->a直接申请,是为了防止内存申请失败;防止数据丢失
if (tmp == NULL) {//也可以使用assert直接终止程序;需要使用aseert.h的头文件
perror("relloc fail");
exit(1);//直接退出程序;也可使用return;
}
//空间增容成功
ps->a = tmp;
ps->capacity = newcappacity;
}
}
//头插
void SLPushFront(SL* ps, SLDataType x) {
//记住SLDataType,这里为我们为了方便(typedef int SLDataType)
assert(ps);//断言一下,防止指针为空
SLCheckCapacity(&ps);//开辟空间
int i = ps->size;
for (; i > 0; i--);//从后往前移位
{
ps->a[i] = ps->a[i - 1];
}
ps->a[0] = x;//此时a[0]就空出来存放x;
ps->size++;//不要忘记size需要++
}
//头删
void SLPopFront(SL* ps) {
assert(ps);
assert(ps->size);//存放的值不能为NULL;
for (int i = 0; i < ps->size-1; i++) {
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
//尾插
void SLPushBack(SL* ps, SLDataType x) {
assert(ps);
void SLCheckCapacity(SL * ps);
ps->a[ps->size++] = x;
//相当于ps->a[ps->size] = x;
//ps->size++;
}
//尾删
void SLPopBack(SL* ps) {
assert(ps);
assert(ps->size);//进行尾删,必须存在尾删的值
ps->size--;
}
//查找
int SLFind(SL* ps, SLDataType x) {
assert(ps);
for (int i = 0; i < ps->size; i++) {
if (ps->a[i] == x) {
return i;
}
}
return -1;
}
//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x) {
assert(ps);
assert(pos >= 0 && ps->size > pos);//pos必须在含有值之间插入
//插入数据:空间够不够
SLCheckCapacity(ps);
//让pos及之后的数据整体往后挪动一位
for (int i = ps->size; i > pos; i--)
{
ps->a[i] = ps->a[i - 1];//a[pos+1] = a[pos]与头插具有相似之处,导致值的覆盖
}
ps->a[pos] = x;//这里的pos对应,数组下标,如果不对应,则按情况+-;
ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos < ps->size);
//与头删类似
for (int i = pos; i < ps->size - 1; i++)
{
ps->a[i] = ps->a[i + 1];
}
ps->size--;
}
void SLPrint(SL s)//对于打印数组,这里不再需要传地址,而是传值
{
for (int i = 0; i < s.size; i++)
{//对于结构体的使用 (.)与(->)的不同
printf("%d ", s.a[i]);
}
printf("\n");
}