aaaaa
1. 线性表
1.1 概念
1.2 举例
生活中的线性表例子非常多,比如一个班级中的以学号编排的学生,一座图书馆中的以序号编排的图书、一条正常排队等候的队列、一摞从上到下堆叠的餐盘,这些都是线性表。他们的特点都是:除了首尾两个元素,其余任何一个元素前后都对应相邻的另一个元素。
注意:线性表是一种数据内部的逻辑关系,与存储形式无关线性表既可以采用连续的顺序存储,也可以采用离散的链式存储
2.顺序表
2.1 基本概念
- 顺序表:顺序存储的线性表。
- 链式表:链式存储的线性表,简称链表。
顺序存储就是将数据存储到一片连续的内存中,在C语言环境下,可以是具名的栈数组,或者是匿名的堆数组。
存储方式不仅仅只是提供数据的存储空间,而是必须要能体现数据之间的逻辑关系。当采用顺序存储的方式来存放数据时,唯一能用来表达数据间本身的逻辑关系的就是存储位置。比如队列中的两个人,小明和小花,如果小明在逻辑上排在相邻的小花的前面,那么在存储位置上也必须把小明存放在相邻的小花的前面。
2.2 基本操作
- 顺序表设计(管理结构体)
-
- 顺序表总容量
- 顺序表当前最末元素下标位置
- 顺序表指针
管理顺序表结构体:
// 管理顺序表的结构体
typedef struct
{
int capcity; // 顺序表容量
int last; // 顺序表最末元素下标
data_t *data; // 顺序表
} sequencelist;
顺序表数据类型:
// 顺序表数据类型
typedef struct data
{
int num;
char name[30];
} data_t;
初始化顺序表:
/// @brief 初始化管理顺序表的结构体
/// @param len 顺序表的容量
/// @return 初始化完成的结构体地址
sequencelist *initCntl(int len)
{
// 在堆内存中申请一个管理顺序表结构体的空间
sequencelist *cntl = (sequencelist *)calloc(1, sizeof(sequencelist));
if (cntl == NULL)
{
printf("申请管理顺序表结构体空间失败.\n");
perror("CALLOC ERROR");
return NULL;
}
// 初始化管理结构体各成员
// 顺序表入口地址以及申请存放顺序表数据空间
cntl->data = (data_t *)calloc(len, sizeof(data_t));
if (cntl->data == NULL)
{
printf("申请顺序表数据空间失败.\n");
perror("CALLOC ERROR");
return NULL;
}
// 顺序表总容量
cntl->capcity = len;
// 顺序表最末元素下标
cntl->last = -1;
return cntl;
}
将数据插入到顺序表中:
/// @brief 将数据头插到顺序表中
/// @param cntl 顺序表
/// @param newData 新数据的地址
/// @return 插入成功返回真,失败返回假
bool addCntlHead(sequencelist *cntl, data_t *newData)
{
// 判断顺序表是否已满,注意顺序表下标从零开始,容量从1开始
if (cntl->last == cntl->capcity - 1)
{
printf("顺序表已满\n");
return false;
}
// 添加数据前更新顺序表下标
cntl->last++;
// 将数据拷贝到顺序表中
// *(cntl->data+cntl->last) = *newData;
// cntl->data[cntl->last] = *newData;
memcpy(cntl->data + cntl->last, newData, sizeof(data_t));
return true;
}
/// @brief 将数据按排序顺序插入到顺序表中
/// @param cntl 顺序表
/// @param newData 新数据的地址
/// @return 插入成功返回真,失败返回假
bool addCntlOrder(sequencelist *cntl, data_t *newData)
{
// 判断顺序表是否已满,注意顺序表下标从零开始,容量从1开始
if (cntl->last == cntl->capcity - 1)
{
printf("顺序表已满.\n");
return false;
}
// 寻找合适位置插入
int tmp;
for (tmp = 0; (newData->num > cntl->data[tmp].num) &&
tmp <= cntl->last;
tmp++)
;
// 将tmp之后的数据右移,留出tmp的位置插入
for (int i = cntl->last; i >= tmp; i--)
{
memcpy(cntl->data + i + 1, cntl->data + i