1.线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上(内存中)并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
2.顺序表
2.1概念及结构
顺序表是用一段
物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。使用顺序表的原因在于,数组有一些缺点。比如c99之前的不支持变长数组。
顺序表是一种储存数据的方式。在语法上允许不连续存放,但顺序表的储存方式要求数据连续存放。
往往会创建两个项目来实现数据结构,一个源文件,一个头文件。使用数据结构时,函数调用即可。
数据结构对细节方面的要求很宽泛,实现方式有很多。
顺序表对储存方式有要求:储存的数据从0(相当于下标,表示位置)开始,依次存储
首先创建SeqList.h和SeqList.c文件
在.h文件中进行结构的定义
#define N 100
struct SeqList——sequence顺序
{
int a[N];
int size;
//记录储存了多少数据
};
这里定义的是一个静态的顺序表,不太实用。因为开小了,不够用;开大了,浪费。
动态顺序表的定义:
struct SeqList
{
int* a;
//使用动态内存开辟来开辟空间
int size;
//记录储存了多少数据,即有效数据个数
int capacity;
//表示存储空间的大小,capacity——容量
};
这样也只能存储int类型的数据,为了存储其他类型的数据,在开头使用typedef重命名:typedef int SLDateType,顺序表中int* a;改为SLDateType* a;
其中SL是SeqList的简写DateType是起的名字,为了防止与后面链表的名字冲突,最好加上前缀。
这样储存其他类型数据时,修改被typedef的类型就行了。
数据结构就是你定义出某种结构出来,可以是顺序表,可以是链表来对数据进行管理。
实现数据结构就是实现对数据增,删,查,改的函数
第一步是初始化函数声明:
void SeqListInit(struct SeqList* psl);
//可以typedef结构体为SeqList//
void SeqListInit(SeqList* psl);
然后涉及动态开辟,使用完后还要销毁,进行销毁函数的声明。
void SeqListDestroy(SeqList* psl);
进行初始化函数定义
void SeqListInit(SeqList* psl)
{
psl->a = NULL;
psl->size = 0;
psl->capacity = 0;
}
还有一种初始化定义方式:
//初始化的方式自由度很高
void SeqListInit(SeqList* psl, int capacity)
//capacity大小为4
{
psl->a = (int*)malloc(capacity);
psl->size = 0;
psl->capacity = 4;
}
写一定量的代码后一定要进行测试,不要写完后进行测试,错误会多到不想改。
然后进行顺序表尾部的数据插入函数(简称尾插)的声明和书写
声明:
void SeqListPushBack(SeqList* psl, SLDateType x);
//尾插
void SeqListPopBack(SeqList* psl);
//尾删
void SeqListPushFront(SeqList* psl, SLDateType x);
//首插
void SeqListPopFront(SeqList* psl);
//首删
书写
void SeqListPushBack(SeqList* psl, SLDateType x);
//尾插
{
if(psl->size == psl->capacity)
//如果相同代表有效数据存满了,需要扩容
{
size_t Newcapacity = psl->capacity == 0 : 4 ? psl -> capacity*2;
//扩容的方式很自由,每次乘2是一个相对合理的方式,视储存的数据而定,选择乘3来扩容,加1来扩容也可以。
SLDateType* tmp = (int*)realloc(p->a, sizeof(SLDateType)* Newcapacity);
if(tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
//终止程序
}
else
{
psl->a = tmp;
psl -> capacity = Newcapacity;
}
}
psl -> a[psl -> size] = x;
//储存数据部分
psl -> size++;
//记录有效数据个数
}
至此首插函数书写完毕,进行函数测试
test.c中
SeqListPushBack(&s , 1);
SeqListPushBack(&s , 2);
SeqListPushBack(&s , 3);
SeqListPushBack(&s , 4);
SeqListPushBack(&s , 5);
//最好测试到5,进行一次扩容
SeqListPrint(&s);
//写一个顺序表打印函数
在SeqList.h和SeqList.c完成打印函数的书写
<