1.线性表
1.概念
一对一的数据所组成的关系称为线性表,注意线性表是逻辑结构
线性表中的数据元素可以是各种各样的,但同一线性表中的元素必定具有相同的特性,即同一数据对象(26个英文字母),相邻的数据之间是一对一的关系,比如B字母节点(数据节点)前面是A字母节点,后面是C字母节点,线性表的特性如下:
(1) 存在唯一的一个被称为"第一个"的数据元素
(2) 存在唯一的一个被称为"最后一个"的数据元素
(3) 除了第一个外,集合中每一个数据元素只有一个前驱节点
(4) 除了最后一个外,集合中每个数据元素均只有一个后驱节点
2.举例
生活中的线性表例子非常多,比如一个班级中的以学号编排的学生一座图书馆中的以序号编排的图书、一条正常排队等候的队列、一摞从上到下堆叠的餐盘,这些都是线性表。他们的特点都是:除了首尾 两个元素,其余任何一个元素前后都对应相邻的另一个元素。
注意:
1.线性表是一种数据内部的逻辑关系,与存储形式无关
2.线性表既可以采用连续的顺序存储(数组),也可以采用离散的 链式存储(链表)
3.顺序表和链表都称为线性表
2.顺序表
1.概念
顺序表:顺序存储的线性表
链式表:链式存储的线性表,简称链表
顺序存储就是将数据存储到一片连续的内存中,在C语言环境下,可以 是具名的栈数组,或者是匿名的堆数组。
存储方式不仅仅只是提供数据的存储空间,而是必须要能体现数据之间 的逻辑关系。当采用顺序存储的方式来存放数据时,唯一能用来表达数 据间本身的逻辑关系的就是存储位置。比如队列中的两个人,小明和小 花,如果小明在逻辑上排在相邻的小花的前面,那么在存储位置上也必 须把小明存放在相邻的小花的前面。
栈空间:char buf[4];
自动申请空间,函数结束后自动释放,{}内定义的局部变量,{}过后自动释放
空间大小为8M
堆空间:malloc(16) calloc(4,sizeof(int)) realloc()
手动分配空间,手动释放空间,空间大小为实际物理内存,空间生命周期为整个程序的生命周期
2.基本操作
1.顺序表设计
一般而言,为了方便操作顺序表,需要一个专门管理顺序表 的"管理结构体",管理结构体一般会包括:
(1) 顺序表总容量
(2) 顺序表当前最末元素下标位置
(3) 顺序表指针
管理结构体示例代码
typedef struct
{
int capacity; // 顺序表容量
int last; // 最末元素下标
int * data; // 顺序表,以整型数据为例
}sequenceList;
初始化
所谓初始化就是建立一个不包含任何元素的顺序表,设置好管理结构体中 的表的总容量、末元素下标,申请好顺序表内存空间等系列准备工作。
下面是初始化顺序表的示例代码:
// 初始化顺序表
sequenceList * init(int cap)
{
sequenceList *s = malloc(sizeof(sequenceList));
if(s == NULL)
return NULL;
s->capacity = cap;
s->last = -1;
s->data = malloc(cap * sizeof(int));
if(s->data == NULL)
{
free(s);
return NULL;
}
return s;
}
增删节点
在顺序表中增加一个数据,可以有多种方式,比如在原数组的末尾增加,或者在原素组的头部增加,或者在中间任意一个位置增加,更具需求来定。
下面是增删示例代码:
// 在表尾插入内容
bool insert(sequenceList *s,int data)
{
if(isFull(s))
return false;
s->data[++s->last] = data;
return true;
}
// 删除数据
bool removeData(sequenceList *s,int data)
{
if(isEmpty(s))
return false;
// 找到要删除的内容
int i = 0;
while(i < s->last)
{
if(s->data[i] == data)
{
break;
}
i++;
}
for(int j = i; j < s->last; j++)
{
s->data[j] = s->data[j+1];
}
s->last--;
return true;
}
销毁顺序表
一个顺序最后不再需要,应当要释放其所占用的内存空间,这被称为顺序表的销毁。
示例代码如下:
void destroy(sequenceList *s)
{
if(s == NULL)
return;
free(s->data);
free(s);
}
题目:
创建一个顺序表,并从键盘接收数字输入,将输入的正整数按从小到大的顺序插入顺序表,并在输入负整数的时候将其绝对值数据删除。每次输入后,将顺序表的内容打印到屏幕上。
3.顺序表的优缺点总结
顺序存储中,由于逻辑关系是用物理位置来表达的,因此从上述示例代码可以很清楚看到,增删数据都是比较繁琐的,需要成片的移动数据。顺序表对数据节点的增删操作是很不友好。
总结其特点如下:
1.优点
不需要多余的信息来记录数据的关系,存储密度高
所有数据顺序存储在一片连续的内存中,支持立即访问任意一个随机数 据,比如上述顺序表中第i个节点是s->data[i]
2.缺点
插入、删除时需要保持数据的物理位置反映其逻辑关系,需要成片移动数据
当数据节点较多时,需要一整片较大的连续内存空间
当数据节点数量变化剧烈时,内存的释放和分配不灵活