数据是依次存储的,具有连续性,是数据连续性不是数字大小连续性。
顺序表分为静态和动态
静态基本就是空间是固定的,需要自己修改;
动态的没有空间就自动扩容。
typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{
SLDataType* a;
int size;//记录存储多少个有效数据
int capicity;//容量空间
}SL;
这整个变量也可以叫做接口,typedef就是容易修改的,设一个变量去表示所对应的类型。
//初始化
//断言很重要
void SLInit(SL* ps)
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
//初始化,先判断指针传过来的数据是否为空指针,然后再对指针内容去初始化。
//释放
void SLInit(SL* ps)
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
void SLCheckCapacity(SL* ps)
{
assert(ps);
//扩容
if (ps->size == ps->capicity)//判断存了数据和大小是否相等,如果相等就是满了
{
int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;//如果=0就返回4,不等于就返回2倍
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);//异常结束
}
ps->a = tmp;//扩容后地址,可能异地扩容所以要给一个新地址
ps->capicity = newcapicity;//扩容成功大小
}
}
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);//不管增加什么数据都要判断一下内存容量,不够就扩容
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
void SLPopFront(SL* ps)
{
assert(ps);
int begin = 1;//从一开始是为了覆盖下标为0的数据,达到删除效果
assert(ps->size > 0);//所存数据必须大于等于一个
while (begin < ps->size)//size-1才是最后一个数据的下标
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;//操作完后就把空间删除
}
//尾部的数据直接添加就行,因为当前的ps->a[ps->size]的下标就是在size的位置,然后size++是要确保size要指向最后一个数据的下一个起始位置
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
//尾部删除就直接size直接减一不打印就行,就可以达到删除效果
void SLPopBack(SL* ps)
{
assert(ps);
//assert(ps);
温柔的检查
//if (ps->size == 0)
//{
//return;
//}
// 暴力的检查
assert(ps->size > 0);//如果报错会直接输出有错误,上述温柔的检查就直接结束
ps->size--;
}
void SLInsert(SL* ps, size_t pos, SLDataType x)
{
assert(ps);
assert(ps->size >= pos);
assert(pos >= 0);//判断下标区间
SLCheckCapacity(ps);//挪动前判断内存是否足够
int end = ps->size-1;//挪动数据
while (end >= pos)//移动到下标那位就行,从后面挪
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;//挪完后,下标就在pos的位置,直接赋值
ps->size++;
}
void SLErase(SL* ps, size_t pos)
{
assert(ps);
assert(ps->size > pos);//尾删就是size-1的位置
assert(pos >= 0);
int begin = pos+1;//这里为什么是1呢?因为如果第一个(下标为0)需要删除的话就是直接可以用下标为1的去覆盖他
while (begin < ps->size)//数据最大的下标是size-1
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
//while (begin >= pos && begin < ps->size)已经定义了begin就取最大区间就行
//{
// ps->a[begin - 1] = ps->a[begin];
// begin++;
//}
// 一开始写的就是这么烂,虽然说效果差不多,哈哈哈。
//这里举例说一下
void TestSeqList1()
{
//要传地址才能修改
SL s1;
SLInit(&s1);//初始化
SLPushBack(&s1,1);
SLPushBack(&s1, 2);
SLPushBack(&s1, 3);
SLPushBack(&s1, 4);
SLPrint(&s1);
SLDestroy(&s1);//销毁
}
int main()
{
TestSeqList1();
return 0;
}
//调试的话就是最好是做好一个调试一个,先别写菜单,写菜单就不那么便于调试
//调试完再写菜单
int SLFind(SL* ps, SLDataType x, int begin)
{
assert(ps);
for (int i = begin; i < ps->size; i++)
{
if (ps->a[i] == x)//等于那个值就有就返回下标
{
return i;
}
}
return -1;
}
//分两种类型
//删除一个,删除全部
int SLFind(SL* ps, SLDataType x, int begin)
{
assert(ps);
for (int i = begin; i < ps->size; i++)
{
if (ps->a[i] == x)
{
return i;//返回下标
}
}
return -1;
}
//首先我们要接收返回值
//假设删除4,然后从下标0开始
int SLF=SLFind(&s1, 4, 0);
if(SLF!=-1)
{
SLErase(&s1, SLF);//调用下标删除函数
}
//删除全部
int SLF=SLFind(&s1, 4, 0);
while(SLF!=-1)
{
SLErase(&s1, SLF);//调用下标删除函数
SLF=SLFind(&s1, 4, SLF);//这次的下标换成上一次删除下标的位置,减少重复计算
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"
int main()
{
SL s;
SLInit(&s);
int option = 0;
int val = 0;
do
{
menu();
printf("请输入你的操作:>");
scanf("%d", &option);
switch (option)
{
case 1:
printf("请依次输入你要尾部插入的数据,以-1结束");
scanf("%d", &val);
while (val != -1)
{
SLPushBack(&s, val);
scanf("%d", &val);
}
break;
case 2:
SLPopBack(&s);
break;
case 3:
printf("请依次输入你要在头部插入的数据,以-1结束");
scanf("%d", &val);
while (val != -1)
{
SLPushFront(&s, val);
scanf("%d", &val);
}
break;
case 4:
SLPopFront(&s);
break;
case 5:
SLPrint(&s);
break;
default:
break;
}
} while (option != -1);
SLDestroy(&s);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include
#include
#include
静态顺序表
//#define N 10
//typedef int SLDataType;//方便修改创建变量
//typedef struct seqList
//{
// SLDataType a[N];
// int size;//记录存储多少个有效数据
//}SL;
//
//动态顺序表--按需要扩容
typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{
SLDataType* a;
int size;//记录存储多少个有效数据
int capicity;//容量空间
}SL;
//打印
void SLPrint(SL* ps);
//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(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);
//pos 下标
// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos);
//查找
int SLFind(SL* ps, SLDataType x,int begin);
#####实现函数
#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"
void SLPrint(SL* ps)
{
assert(ps);
int i = 0;
for (i = 0; i < ps->size; i++)
{
printf("%d", ps->a[i]);
}
printf("\n");
}
void SLCheckCapacity(SL* ps)
{
assert(ps);
//扩容
if (ps->size == ps->capicity)
{
int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;//扩容后地址
ps->capicity = newcapicity;//扩容成功大小
}
}
void SLInit(SL* ps)
{
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
void SLDestroy(SL* ps)
{
assert(ps);
if (ps->a)
{
free(ps->a);
ps->a = NULL;
ps->size = 0;
ps->capicity = 0;
}
}
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
ps->a[ps->size] = x;
ps->size++;
}
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps->size > 0);
ps->size--;
}
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
int end = ps->size - 1;
while (end >= 0)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
void SLPopFront(SL* ps)
{
assert(ps);
int begin = 1;
assert(ps->size > 0);
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
void SLInsert(SL* ps, size_t pos, SLDataType x)
{
assert(ps);
assert(ps->size >= pos);
assert(pos >= 0);
SLCheckCapacity(ps);
int end = ps->size-1;
while (end >= pos)
{
ps->a[end + 1] = ps->a[end];
end--;
}
ps->a[ps->size] = x;
ps->size++;
}
void SLErase(SL* ps, size_t pos)
{
assert(ps);
assert(ps->size >= pos);//尾删就是size-1的位置
assert(pos >= 0);
int begin = pos+1;
while (begin < ps->size)
{
ps->a[begin - 1] = ps->a[begin];
begin++;
}
ps->size--;
}
int SLFind(SL* ps, SLDataType x, int begin)
{
assert(ps);
for (int i = begin; i < ps->size; ++i)
{
if (ps->a[i] == x)
{
return i;
}
}
return -1;
}