线性表
线性表时一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串
线性表在逻辑上的存储是线性结构,但在物理结构上并不一定是连续的,它通常以数组和链式结构进行存储
顺序表
顺序表的结构就是一段连续的空间
概念及其结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构。因为其特性所以一般采取数组存储。
顺序表分为:
1.静态顺序表:用于定长数组存储
2.动态顺序表:用于动态开辟数组进行存储
其方法如下:
//顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct Seqlist
{
SLDataType arr[N];//定长数组
size_t size;//有效个数
}Seqlist;
//顺序表的动态存储
typedef struct Seqlist
{
SLDataType* arr;//动态开辟的数组
size_t size;//有效个数
size_t capacity;//空间大小
}Seqlist;
顺序表的基本操作
由于静态顺序表使用较少,在这里模拟实现动态顺序表的相关功能与操作。
(1)顺序表的初始化
初始化顺序表就是将顺序表置空,所以只需要将顺序表的有效个数置为0即可,同时我们知道顺序表的结构类似于数组,所以我们要对其空间进行开辟,只有开辟了空间,顺序表的后续操作才可以完成。
void SeqListInit(SeqList * ps)
{
assert(ps);
ps->capacity = SEQLIST_SIZE;
ps->a = (SLDateType*)malloc(sizeof(SLDateType)*ps->capacity);
ps->size = 0;
}
(2)顺序表的销毁
销毁顺序表就是将表中的元素删除,删除的操作也非常的简单,只需要清空元素,将其内存和有效元素都置为0
void SeqListDestory(SeqList* ps)//销毁顺序表
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->size = ps->capacity = 0;
}
(3)打印顺序表中的元素
检查顺序表是否为空,使用for循环依次遍历输出其元素内容
void SeqListPrint(SeqList* ps)//打印顺序表
{
assert(ps);
for (size_t i = 0; i < ps->size; ++i)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
(4)检查空间,如果满了对其进行扩容
在对顺序表进行插入操作时,为避免出现内存不够,内容溢出现象,在插入元素前需要对顺序表进行空间检查,若空间不够,使用realloc动态内存开辟空间
void CheckCapacity(SeqList* ps)//增容检查
{
assert(ps);
if (ps->size == ps->capacity)
{
size_t newcapacity = ps->capacity = 0 ? 4 : ps->capacity * 2;
ps->a = (SLDateType*)realloc(ps->a, newcapacity*sizeof(SLDateType));
ps->capacity = newcapacity;
}
}
(5)尾插
尾插法顾名思义就是在顺序表的末尾进行插入元素的操作,在表不为空的情况下对其进行空间检测,判断顺序表是否已满,将插入元素的值赋给顺序表中的最后一个元素的下一个元素ps->a[ps->size++] = x; 插入后有效个数发生变化size++;
void SeqListPushBack(SeqList* ps, SLDateType x)//顺序表尾插
{
assert(ps);
CheckCapacity(ps);
ps->