《C语言动态顺序表:从内存管理到功能实现》
1.顺序表
1.1 概念
- 顺序存储的线性表,叫顺序表。
1.2顺序表存放的实现方式
- 可以使用数组存储数据,可以实现逻辑上相连,物理内存上也相连。
- 也可以使用malloc在堆区申请一片连续的空间,存放数据,实现逻辑上相连,物理内存上也相连。
1.3 顺序表的组成
- 需要一片连续的空间,存放数据。 可以是数组,也可以是连续堆区空间
- 还需要一个变量来记录当前顺序表的长度。(已存放的元素个数)

1.4 对顺序表长度的解析
- 顺序表的长度能够表示顺序表中实际使用的元素个数
- 也能够表示数组中第一个没有存放数据元素的数组元素下标
- 要遍历整个顺序表时,顺序表的长度是最大上限
1.5 顺序表结构体类型
#define MAX 20 //顺序表最大容量
typedef int datatype; //数据元素类型//定义顺序表结构体类型
typedef struct
{datatype data[MAX]; //存放顺序表的数组int len; //顺序表的长度
}SeqList, *SeqListPtr;
2.有关顺序表函数的操作

2.1创建顺序表
2.1.1函数功能概述
create_seq 函数的主要功能是在堆区动态分配内存来创建一个顺序表,并对其进行初始化,最后返回指向该顺序表的指针。
2.1.2实现步骤
- 内存分配:
- 使用
malloc函数在堆区分配一块大小为sizeof(seq_list)的内存空间,用于存储顺序表。 - 将分配的内存地址强制转换为
seq_p类型,并赋值给指针S。
- 使用
- 检查分配结果:
- 检查
S是否为NULL,如果为NULL说明内存分配失败,输出错误信息并返回NULL。
- 检查
- 初始化顺序表长度:
- 将顺序表的长度
S->len初始化为 0,表示顺序表中当前没有元素。
- 将顺序表的长度
- 初始化数组元素:
- 使用
bzero函数将顺序表中存储元素的数组S->data全部置为 0,确保数组中的元素初始值为 0。
- 使用
- 返回指针:
- 返回指向新创建并初始化好的顺序表的指针
S。
- 返回指向新创建并初始化好的顺序表的指针
//创建顺序表
seq_p create_seq()
{// 从堆区申请一个顺序表的空间// 使用 malloc 函数分配足够的内存空间,大小为 seq_list 结构体的大小// 将分配的内存地址强制转换为 seq_p 类型,并赋值给指针 Sseq_p S = (seq_p)malloc(sizeof(seq_list));// 检查内存分配是否成功if(S == NULL){// 若分配失败,输出错误信息并返回 NULLprintf("空间申请失败\n");return NULL;}// seq_list 类型结构体, len 表示为数组长度, 顺序表长度为 0// 初始化顺序表的长度为 0,表示当前顺序表中没有元素S->len = 0;// seq_list 类型结构体内的数组内的元素置零// 使用 bzero 函数将顺序表中存储元素的数组 data 全部置为 0// 第一个参数是要置零的内存块的起始地址,即 S->data// 第二个参数是要置零的内存块的大小,即 sizeof(S->data)bzero(S->data, sizeof(S->data));// 返回指向新创建并初始化好的顺序表的指针return S;
}
2.2判空
2.2.1函数功能概述
empty_seq 函数的主要功能是判断一个顺序表是否为空。顺序表是一种线性表的顺序存储结构,通常使用数组来实现。该函数通过检查顺序表的长度来确定其是否为空。
2.2.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.2.3实现步骤
- 参数有效性检查:
- 首先检查传入的顺序表指针
S是否为空。如果为空,说明传入的参数无效,输出错误信息并返回 -1。
- 首先检查传入的顺序表指针
- 判断顺序表是否为空:
- 使用三目运算符
S->len == 0? 1 : 0来判断顺序表的长度是否为 0。 - 如果
S->len等于 0,说明顺序表为空,函数返回 1。 - 如果
S->len不等于 0,说明顺序表不为空,函数返回 0。
- 使用三目运算符
//判空
int empty_seq(seq_p S)
{// 入参合理性判断// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回 -1printf("入参为空\n");return -1;}// 判断顺序表的长度是否为 0// 如果长度为 0,说明顺序表为空,返回 1// 如果长度不为 0,说明顺序表不为空,返回 0return S->len == 0? 1 : 0; // 空返回真,非空返回假也就是 0;
}
2.3判满
2.3.1函数功能概述
full_seq 函数用于判断顺序表是否已满。顺序表是一种线性表的顺序存储结构,通常使用数组来实现,有固定的最大容量。该函数通过比较顺序表当前元素个数和最大容量来确定顺序表是否已满。
2.3.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.3.3实现步骤
- 参数有效性检查:
- 首先检查传入的顺序表指针
S是否为空。若为空,表明传入的参数无效,输出错误信息并返回 -1。
- 首先检查传入的顺序表指针
- 判断顺序表是否已满:
- 使用三目运算符
S->len == MAX? 1 : 0来比较顺序表当前元素个数S->len和最大容量MAX。 - 若
S->len等于MAX,意味着顺序表已满,函数返回 1。 - 若
S->len不等于MAX,表示顺序表未满,函数返回 0。
- 使用三目运算符
//判满
int full_seq(seq_p S)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回 -1printf("入参为空\n");return -1;}// 判断顺序表是否已满// 通过比较顺序表当前元素个数 S->len 和最大容量 MAX// 如果两者相等,说明顺序表已满,返回 1// 如果不相等,说明顺序表未满,返回 0return S->len == MAX? 1 : 0; // 判断 data 实际元素个数的长度,是否等于 data 最大长度
}
2.4头插
头插的核心:元素循环后移,再头插
2.4.1函数功能概述
inser_head 函数的主要功能是在顺序表的头部插入一个新元素。顺序表是一种线性表的顺序存储结构,通常使用数组来实现。该函数会将顺序表中现有的元素依次向后移动一位,然后将新元素插入到顺序表的第一个位置。
2.4.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。datatype data:要插入到顺序表头部的元素,datatype是自定义的数据类型。
2.4.3实现步骤
- 参数有效性检查:
- 首先检查传入的顺序表指针
S是否为空。如果为空,说明传入的参数无效,输出错误信息并返回。
- 首先检查传入的顺序表指针
- 判断顺序表是否已满:
- 调用
full_seq函数判断顺序表是否已满。如果已满,输出提示信息并返回,因为无法再插入新元素。
- 调用
- 元素后移:
- 使用
for循环从顺序表的最后一个元素开始,将每个元素依次向后移动一位,为新元素腾出第一个位置。
- 使用
- 插入新元素:
- 将新元素
data插入到顺序表的第一个位置,即S->data[0]。
- 将新元素
- 更新顺序表长度:
- 插入新元素后,将顺序表的长度
S->len加 1,表示顺序表中元素的数量增加了一个。
- 插入新元素后,将顺序表的长度
//头插
//往哪插入的顺序表,例如seq_p类型 S是他的操作顺序表,datatype类型的datatype
//
void inser_head(seq_p S, datatype data)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return;}// 判满// 调用 full_seq 函数判断顺序表是否已满if(full_seq(S)){// 若已满,输出提示信息并返回printf("表已满,不能插入\n");return;}// 元素后移// 从顺序表的最后一个元素开始,将每个元素依次向后移动一位for(int i = S->len - 1; i >= 0; i--){// 将第 i 个元素移动到第 i + 1 个位置S->data[i + 1] = S->data[i];}// 第一位位置可以被覆盖// 将新元素插入到顺序表的第一个位置S->data[0] = data; // 第一个位置等于传过来的 data 就可以了// 顺序表长度自增// 插入新元素后,顺序表的长度加 1S->len++;
}
2.5输出顺序表
2.5.1函数功能概述
show 函数的主要功能是输出顺序表中的所有元素。顺序表是一种线性表的顺序存储结构,通常使用数组来实现。该函数会遍历顺序表中的每个元素并将其打印输出。
2.5.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.5.3实现步骤
- 参数有效性检查:
- 首先检查传入的顺序表指针
S是否为空。如果为空,说明传入的参数无效,输出错误信息并返回。
- 首先检查传入的顺序表指针
- 判断顺序表是否为空:
- 调用
empty_seq函数判断顺序表是否为空。如果为空,输出提示信息并返回,因为空顺序表没有元素可输出。
- 调用
- 遍历并输出元素:
- 使用
for循环遍历顺序表中的每个元素,从第一个元素(索引为 0)到最后一个元素(索引为S->len - 1)。 - 在每次循环中,使用
printf函数输出当前元素的值。
- 使用
// 输出顺序表
void show(seq_p S)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return; }// 判空// 调用 empty_seq 函数判断顺序表是否为空if(empty_seq(S)){// 若为空,输出提示信息并返回printf("入参为空\n");return;}// 遍历顺序表并输出元素for(int i = 0; i < S->len; i++){// 打印顺序表中的每个元素printf("输出顺序表%d\n", S->data[i]);}
}
2.6尾插
2.6.1函数功能概述
inser_tail 函数用于在顺序表的尾部插入一个新元素。顺序表是用连续的存储单元依次存储数据元素的线性结构,该函数会在顺序表的末尾添加新元素,并更新顺序表的长度。
2.6.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。datatype data:要插入到顺序表尾部的元素,datatype是自定义的数据类型。
2.6.3实现步骤
- 参数有效性检查:
- 检查传入的顺序表指针
S是否为空。若为空,输出错误信息并终止函数执行。
- 检查传入的顺序表指针
- 判断顺序表是否已满:
- 调用
full_seq函数判断顺序表是否已满。若已满,输出提示信息并终止函数执行。
- 调用
- 插入新元素:
- 若顺序表不为空且未满,将新元素
data插入到S->data[S->len]位置,即顺序表的尾部。
- 若顺序表不为空且未满,将新元素
- 更新顺序表长度:
- 插入新元素后,将顺序表的长度
S->len加 1。
- 插入新元素后,将顺序表的长度
//尾插
void inser_tail(seq_p S, datatype data)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return; }// 判满// 调用 full_seq 函数判断顺序表是否已满if(full_seq(S)){// 若已满,输出提示信息并返回printf("表已满,不能插入\n");return;}// 在顺序表尾部插入新元素// S->len 表示当前顺序表的长度,也就是新元素要插入的位置S->data[S->len] = data;// 插入新元素后,顺序表长度加 1S->len++;
}
2.7头删
2.7.1函数功能概述
dele_head 函数的主要功能是删除顺序表的第一个元素。顺序表是一种线性表的顺序存储结构,通常使用数组来实现。该函数会将顺序表中除第一个元素外的其他元素依次向前移动一位,覆盖掉原来的第一个元素,从而实现删除操作。
2.7.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.7.3实现步骤
- 参数有效性检查:
- 首先检查传入的顺序表指针
S是否为空。如果为空,说明传入的参数无效,输出错误信息并返回。
- 首先检查传入的顺序表指针
- 判断顺序表是否为空:
- 调用
empty_seq函数判断顺序表是否为空。如果为空,输出提示信息并返回,因为空顺序表没有元素可删除。
- 调用
- 元素前移:
- 使用
for循环从顺序表的第二个元素(索引为 1)开始,将每个元素依次向前移动一位,覆盖掉原来的第一个元素。
- 使用
- 更新顺序表长度:
- 删除元素后,将顺序表的长度
S->len减 1,表示顺序表中元素的数量减少了一个。
- 删除元素后,将顺序表的长度
//头删
void dele_head(seq_p S)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return;}// 判空// 调用 empty_seq 函数判断顺序表是否为空if(empty_seq(S)){// 若为空,输出提示信息并返回printf("表为空,无需删除\n");return;}// i:代表要移动的元素// 从顺序表的第二个元素开始,将每个元素依次向前移动一位for(int i = 1; i < S->len; i++){// i - 1 表示了 i 的前面的一个元素// 将第 i 个元素移动到第 i - 1 个位置S->data[i - 1] = S->data[i];}// 删除元素后,顺序表长度减 1S->len--;
}
2.8清空顺序表
2.8.1函数功能概述
clear_seq 函数的主要功能是清空顺序表。这里的清空操作并非真正释放顺序表占用的内存,而是将顺序表的长度置为 0,意味着顺序表中不再有有效元素。
2.8.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.8.3实现步骤
- 参数有效性检查:
- 检查传入的顺序表指针
S是否为空。若为空,输出错误信息并终止函数执行。
- 检查传入的顺序表指针
- 清空顺序表:
- 若指针有效,将顺序表的长度
S->len置为 0。由于顺序表的有效元素是通过长度来界定的,长度为 0 就表示顺序表为空。
- 若指针有效,将顺序表的长度
//清空顺序表
void clear_seq(seq_p S)
{// 入参合理性检查// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return;}// 直接将长度置零// 把顺序表的长度 S->len 设为 0,这样顺序表就被视为没有有效元素了S->len = 0;
}
2.9按位置插入
2.9.1函数功能概述
insert_pos 函数用于在顺序表的指定位置插入一个新元素。顺序表是一种线性表的顺序存储结构,该函数会将指定位置及之后的元素依次向后移动一位,然后将新元素插入到指定位置。

2.9.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。datatype data:要插入到顺序表中的元素,datatype是自定义的数据类型。int pos:要插入元素的位置,位置从 1 开始计数。
2.9.3实现步骤
//按位置插入
//需要三个参数,1.顺序表(S),数据(data),位置(pos)void insert_pos(seq_p S, datatype data, int pos)
{// 检查传入的顺序表指针是否为空if(S == NULL){// 如果为空,输出错误信息并返回printf("入参为空\n");return;}// 调用 full_seq 函数判断顺序表是否已满if(full_seq(S)){// 如果已满,输出错误信息并返回printf("表已满\n");return;}// 检查插入位置是否合理if(pos <= 0 || pos > S->len + 1){// 如果位置不合理(小于等于 0 或者大于当前长度加 1),输出错误信息并返回printf("位置不合理\n");return;}// 1. 从顺序表的最后一个元素开始,逐个向后移动元素,直到要插入的位置// 2. S->len - 1: 当前顺序表的最后一个元素的索引// 3. pos - 1: 要插入的位置的索引(从 0 开始)for(int i = S->len - 1; i >= pos - 1; i--){// 将第 i 个元素移动到第 i + 1 个位置// 通过循环将从 pos - 1 到 S->len - 1 的所有元素向后移动一位S->data[i + 1] = S->data[i];}// 循环结束后,插入位置已经空出// 将新元素插入到指定位置S->data[pos - 1] = data;// 顺序表的长度加 1S->len++;
}
2.10按位删除
2.10.1函数功能概述
dele_pos 函数的主要功能是从顺序表中删除指定位置的元素。顺序表是一种线性表的顺序存储结构,该函数会将指定位置之后的元素依次向前移动一位,覆盖掉要删除的元素,从而实现删除操作。
2.10.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。int pos:要删除元素的位置,位置从 1 开始计数。
2.10.3实现步骤
- 参数有效性检查:
- 检查传入的顺序表指针
S是否为空。如果为空,说明传入的参数无效,输出错误信息并返回。 - 调用
empty_seq函数判断顺序表是否为空。如果为空,输出提示信息并返回,因为空顺序表没有元素可删除。 - 检查删除位置
pos是否合理。如果pos小于等于 0 或者大于顺序表的当前长度S->len,说明位置不合理,输出错误信息并返回。
- 检查传入的顺序表指针
- 元素前移:
- 使用
for循环从要删除元素的位置pos开始,将该位置之后的元素依次向前移动一位,覆盖掉要删除的元素。
- 使用
- 更新顺序表长度:
- 删除元素后,将顺序表的长度
S->len减 1,表示顺序表中元素的数量减少了一个。
- 删除元素后,将顺序表的长度
//按位删除
//简单理解:把len循环到要删除的下标后,把当前的数据赋值给当前前一位
void dele_pos(seq_p S, int pos)
{// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return;}// 调用 empty_seq 函数判断顺序表是否为空if(empty_seq(S)){// 若为空,输出提示信息并返回printf("表为空,无需删除\n");return;}// 位置合理性检查if(pos <= 0 || pos > S->len){// 若位置不合理(小于等于 0 或者大于当前顺序表长度),输出错误信息并返回printf("位置不合理\n");return;}// 循环前移for(int i = pos; i <= S->len - 1; i++){// 将第 i 个位置的元素前移到第 i - 1 个位置S->data[i - 1] = S->data[i];}// 顺序表长度减 1S->len--;
}
2.11顺序表去重
2.11.1函数功能概述
dele 函数的主要功能是对顺序表进行去重操作,即移除顺序表中重复的元素,只保留每个元素的一个副本。
2.11.2函数参数
seq_p S:指向顺序表的指针,seq_p应该是自定义的指向顺序表结构体的指针类型。
2.11.3实现步骤
- 参数有效性检查:
- 检查传入的顺序表指针
S是否为空。若为空,输出错误信息并返回。 - 调用
empty_seq函数判断顺序表是否为空。若为空,输出提示信息并返回。 - 检查顺序表的长度是否为 1。若为 1,说明顺序表中只有一个元素,无需去重,输出提示信息并返回。
- 检查传入的顺序表指针
- 去重操作:
- 使用外层
for循环遍历顺序表中的每一个元素,索引为i。 - 对于每个元素,使用内层
for循环从i + 1开始遍历剩余的元素,索引为j。 - 比较
S->data[i]和S->data[j]是否相等。若相等,说明找到了重复元素。 - 调用
dele_pos函数删除重复元素,注意传入的位置是j + 1,因为位置从 1 开始计数。 - 删除元素后,由于后面的元素会前移,原来
j位置的元素被新元素覆盖,需要将j减 1,以便重新判断该位置的元素。
- 使用外层
//顺序表的去重
void dele(seq_p S)
{// 检查传入的顺序表指针是否为空if(S == NULL){// 若为空,输出错误信息并返回printf("入参为空\n");return;}// 调用 empty_seq 函数判断顺序表是否为空if(empty_seq(S)){// 若为空,输出提示信息并返回printf("表为空\n");return;}// 检查顺序表中是否只有一个元素if(S->len == 1){// 若只有一个元素,输出提示信息并返回printf("表中只有一个元素\n");return;}//找到重复元素,再去重// 先循环遍历顺序表表中的每一个元素for(int i = 0; i < S->len; i++){// 每拿到一个元素,和剩余的元素比较是否相同for(int j = i + 1; j < S->len; j++){// 判断元素是否相等if(S->data[i] == S->data[j]){// 拿到相同元素下标后,调用按位置删除函数dele_pos(S, j + 1);// 按位置删除后,原来已经判断过的位置,被新的元素覆盖了需要重新判断j--; }}}
}
2.12顺序表释放
2.12.1函数功能概述
free_seq 函数的主要功能是释放顺序表所占用的动态内存,并将指向顺序表的指针置为 NULL,以避免悬空指针问题。该函数接收一个指向顺序表指针的指针(二级指针)作为参数,这样可以在函数内部修改原指针的值。
2.12.2函数参数
seq_p *S:指向顺序表指针的指针(二级指针),seq_p应该是自定义的指向顺序表结构体的指针类型。
2.12.3实现步骤
- 参数有效性检查:
- 检查传入的二级指针
S是否为空,或者S所指向的一级指针*S是否为空。如果其中任何一个为空,说明入参无效,输出错误信息并返回,避免对空指针进行操作。
- 检查传入的二级指针
- 释放内存:
- 若参数有效,调用
free函数释放*S所指向的内存空间,即释放顺序表所占用的动态内存。
- 若参数有效,调用
- 避免悬空指针:
- 释放内存后,将
*S置为NULL,这样可以避免原指针成为悬空指针,提高程序的安全性。
- 释放内存后,将
//释放顺序表
//可以传一级指针,但是不能给主函数中的S置空
void free_seq(seq_p *S)
{// S==NULL 和 *S==NULL 不能交换位置,因为 S 是一个二级指针,要先判断二级指针不为空,再判断二级指针指向的内容不为空if(S == NULL || *S == NULL){// 若传入的二级指针 S 为空,或者 S 所指向的一级指针 *S 为空,说明入参无效// 输出错误信息并返回,避免对空指针进行操作printf("入参为空\n");return;}// 调用 free 函数释放 S 所指向的一级指针 *S 所指向的内存空间// 即释放顺序表所占用的动态内存free(*S);// 将 S 所指向的一级指针 *S 置为 NULL// 这样可以避免原指针成为悬空指针,提高程序的安全性*S = NULL;
}
3. 主函数
3.1代码功能概述
使用自定义顺序表库 seq_list.h 的测试程序,它展示了顺序表的各种操作,包括创建、判空、判满、插入(头插、尾插、按位置插入)、删除(头删、按位置删除)、去重、清空以及释放内存等操作,并在每次操作后打印相应的提示信息和顺序表的内容,方便观察操作结果。
3.2实现步骤
- 创建顺序表:调用
create_seq函数创建一个顺序表,并将其指针赋值给S。 - 初始状态检查:调用
empty_seq和full_seq函数分别判断顺序表是否为空和已满,并打印结果。然后调用show函数打印顺序表的内容。 - 插入操作:
- 使用
inser_head函数在顺序表头部插入多个元素。 - 使用
inser_tail函数在顺序表尾部插入一个元素。 - 使用
insert_pos函数在顺序表的指定位置插入一个元素。
- 使用
- 删除操作:
- 使用
dele_head函数删除顺序表的第一个元素。 - 使用
dele_pos函数删除顺序表的指定位置的元素。
- 使用
- 其他操作:
- 使用
clear_seq函数清空顺序表。 - 使用
dele函数对顺序表进行去重操作。
- 使用
- 释放内存:调用
free_seq函数释放顺序表所占用的内存,并将指针置为NULL,最后打印指针的值。
#include "seq_list.h"int main(int argc, const char *argv[])
{// 调用创建顺序表函数,创建一个顺序表并将其指针赋值给 Sseq_p S = create_seq(); // 调用 empty_seq 函数判断顺序表是否为空,并打印结果printf("判空%d\n", empty_seq(S));// 调用 full_seq 函数判断顺序表是否已满,并打印结果printf("判满%d\n", full_seq(S));// 调用 show 函数打印顺序表的内容show(S);// 多次调用 inser_head 函数在顺序表头部插入元素inser_head(S, 80);inser_head(S, 81);inser_head(S, 82);inser_head(S, 90);// 打印提示信息,表示接下来要打印现有顺序表的值printf("打印现有值---------\n");// 再次调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要进行尾插操作printf("打印尾插-------------\n");// 调用 inser_tail 函数在顺序表尾部插入元素 66inser_tail(S, 66); // 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要进行头删操作printf("打印头删-------------\n");// 调用 dele_head 函数删除顺序表的第一个元素dele_head(S); // 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要清空顺序表printf("清空顺序表------------\n");// 调用 clear_seq 函数清空顺序表clear_seq(S); // 调用 show 函数打印顺序表的内容show(S);// 再次调用 dele_head 函数尝试删除元素,此时顺序表可能为空dele_head(S); // 打印提示信息,表示接下来要进行按位置插入操作printf("按位置插入------------\n");// 调用 insert_pos 函数在顺序表的第 3 个位置插入元素 99insert_pos(S, 99, 3); // 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要进行多次头插操作printf("头插几个数据------------\n");// 多次调用 inser_head 函数在顺序表头部插入元素inser_head(S, 99);inser_head(S, 98);inser_head(S, 20);inser_head(S, 99);// 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要进行按位置删除操作printf("按位置删除3------------\n");// 调用 dele_pos 函数删除顺序表的第 3 个元素dele_pos(S, 3);// 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要进行顺序表去重操作printf("顺序表去重------------\n");// 调用 dele 函数对顺序表进行去重操作dele(S);// 调用 show 函数打印顺序表的内容show(S);// 打印提示信息,表示接下来要释放顺序表的内存printf("释放内存------------\n");// 调用 free_seq 函数释放顺序表所占用的内存,并将指针置为 NULLfree_seq(&S);// 打印顺序表指针 S 的值,此时应为 NULLprintf("%p\n", S);return 0;
}
4. 全局函数声明
4.1代码功能概述
定义一个名为 seq_list.h 的头文件,它定义了顺序表的相关数据结构和操作函数的声明,用于实现顺序表的基本功能,如创建、插入、删除、判空、判满等操作。
4.2实现操作步骤
- 头文件保护:使用
#ifndef、#define和#endif防止头文件被重复包含。 - 包含必要的头文件:包含了
stdio.h、string.h和stdlib.h头文件,用于输入输出、字符串操作和内存管理。 - 定义常量和数据类型:
#define MAX 7定义了顺序表的最大容量为 7。typedef int datatype定义了顺序表中元素的数据类型为int。
- 定义顺序表结构体:
typedef struct seq_list定义了顺序表的结构体,包含一个存储元素的数组data和一个记录长度的变量len。 - 函数声明:声明了一系列用于操作顺序表的函数,包括创建、插入、删除、判空、判满等操作。
#ifndef __SEQ_LIST_H__
#define __SEQ_LIST_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>// 定义顺序表的最大容量为 7
#define MAX 7// 定义数据类型为 int
typedef int datatype;// 定义顺序表的结构体
typedef struct seq_list
{// 用于存储顺序表元素的数组datatype data[MAX];// 记录顺序表当前的长度int len;
} seq_list, *seq_p;// 创建顺序表
// 返回值:指向新创建顺序表的指针
seq_p create_seq();// 判空
// 参数 S:指向顺序表的指针
// 返回值:若顺序表为空返回 1,否则返回 0
int empty_seq(seq_p S);// 判满
// 参数 S:指向顺序表的指针
// 返回值:若顺序表已满返回 1,否则返回 0
int full_seq(seq_p S);// 头插
// 参数 S:指向顺序表的指针
// 参数 data:要插入的数据
void inser_head(seq_p S, datatype data);// 输出顺序表
// 参数 S:指向顺序表的指针
void show(seq_p S);// 尾插
// 参数 S:指向顺序表的指针
// 参数 data:要插入的数据
void inser_tail(seq_p S, datatype data);// 头删
// 参数 S:指向顺序表的指针
void dele_head(seq_p S);// 清空顺序表
// 参数 S:指向顺序表的指针
void clear_seq(seq_p S);// 按位置插入
// 参数 S:指向顺序表的指针
// 参数 data:要插入的数据
// 参数 pos:插入的位置
void insert_pos(seq_p S, datatype data, int pos);// 按位删除
// 参数 S:指向顺序表的指针
// 参数 pos:要删除元素的位置
void dele_pos(seq_p S, int pos);// 顺序表的去重
// 参数 S:指向顺序表的指针
void dele(seq_p S);// 释放顺序表
// 参数 S:指向顺序表指针的指针
// 说明:可以传一级指针,但不能给主函数中的 S 置空
void free_seq(seq_p *S);#endif
#ubuntu@GAOLANG:~/data/GQ1$
4.3 代码运行结果展现


相关文章:
《C语言动态顺序表:从内存管理到功能实现》
1.顺序表 1.1 概念 顺序存储的线性表,叫顺序表。 1.2顺序表存放的实现方式 可以使用数组存储数据,可以实现逻辑上相连,物理内存上也相连。也可以使用malloc在堆区申请一片连续的空间,存放数据,实现逻辑上相连&#…...
通过API 调用本地部署 deepseek-r1 模型
如何本地部署 deepseek 请参考(windows 部署安装 大模型 DeepSeek-R1) 那么实际使用中需要开启API模式,这样可以无拘无束地通过API集成的方式,集成到各种第三方系统和应用当中。 上遍文章是基于Ollama框架运行了deepSeek R1模型…...
DeepSeek-学习与实践
1.应用场景 主要用于学习与使用DeepSeek解决问题, 提高效率. 2.学习/操作 1.文档阅读 文档 DeepSeek -- 官网, 直接使用 --- 代理网站 --- 极客智坊 https://poe.com/DeepSeek-R1 https://time.geekbang.com/search?qdeepseek -- 搜索deepseek的资料 资料 20250209DeepSeekC…...
DeepSeek和ChatGPT的全面对比
一、模型基础架构对比(2023技术版本) 维度DeepSeekChatGPT模型家族LLAMA架构改进GPT-4优化版本参数量级开放7B/35B/120B闭源175B位置编码RoPE NTK扩展ALiBiAttention机制FlashAttention-3FlashAttention-2激活函数SwiGLU ProGeGLU训练框架DeepSpeedMeg…...
无线网络安全配置指南:WPA、WPA2、WPA3及WAPI详解
对于做 Wi-Fi 的朋友,大家可能天天都需要配置各种加密和模式,但是有时候可能会一时忘记如何配置,基于日常的工作经验,总结了一篇文档:《无线网络安全配置指南:WPA、WPA2、WPA3及WAPI详解》,具体…...
撕碎QT面具(6):调节窗口大小后,控件被挤得重叠的解决方法
问题:控件重叠 分析原因:因为设置了最小大小,所以界面中的大小不会随窗口的变化而自动变化。 处理方案:修改mimumSize的宽度与高度为0,并设置sizePolicy为Expanding,让其自动伸缩。 结果展示(自…...
解锁机器学习核心算法 | K-平均:揭开K-平均算法的神秘面纱
一、引言 机器学习算法种类繁多,它们各自有着独特的优势和应用场景。前面我们学习了线性回归算法、逻辑回归算法、决策树算法。而今天,我们要深入探讨的是其中一种经典且广泛应用的聚类算法 —— K - 平均算法(K-Means Algorithm)…...
【Linux】匿名管道的应用场景-----管道进程池
目录 一、池化技术 二、简易进程池的实现: Makefile task.h task.cpp Initchannel函数: 创建任务: 控制子进程: 子进程执行任务: 清理收尾: 三、全部代码: 前言: 对于管…...
机器学习(1)安装Pytorch
1.安装命令 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 2.安装过程Log: Looking in indexes: https://download.pytorch.org/whl/cu118 Co…...
Linux 多Python版本统一和 PySpark 依赖 python 包方案
背景 Linux 服务器经常有多个Python版本,比如 Python2 有两个版本,Python3 有两个版本。在使用上容易混淆,而且有些需要新增一些 module 更容易,安装如果路径不统一,导致日常使用时,会出现找不到新安装mod…...
PostgreSQL的学习心得和知识总结(一百六十九)|深入理解PostgreSQL数据库之 Group By 键值消除 的使用和实现
目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库…...
DeepSeek是什么?两种模型的对比?
最近DeepSeek的风也是很大,它也是很火,那么DeepSeek是什么呢? 什么是DeepSeek? DeepSeek是一家专注通用人工智能(AGI)的中国科技公司,主攻大模型研发与应用。DeepSeek-R1是其开源的推理模型&a…...
跟着 Lua 5.1 官方参考文档学习 Lua (2)
文章目录 2.3 – Variables2.4 – Statements2.4.1 – Chunks2.4.2 – Blocks2.4.3 – Assignment2.4.4 – Control Structures2.4.5 – For Statement2.4.6 – Function Calls as Statements2.4.7 – Local Declarations 2.3 – Variables Variables are places that store v…...
Python基于循环神经网络的情感分类系统(附源码,文档说明)
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
Zookeeper应用案例-分布式锁-实现思路
以下是具体实现代码 第一步:注册锁节点 第二步:获取锁节点,如果自己是最小的节点,就获取权限 第三步:拿到锁就开始自己的业务逻辑 第四步:业务逻辑好了就要释放这把锁 第五步:重新注册监听&…...
java练习(32)
ps:题目来自力扣 环形链表 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表…...
伯克利 CS61A 课堂笔记 10 —— Trees
本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理,全英文内容,文末附词汇解释。 目录 01 Trees 树 Ⅰ Tree Abstraction Ⅱ Implementing the Tree Abstraction 02 Tree Processing 建树过程 Ⅰ Fibonacci tree Ⅱ Tree Process…...
让编程变成一种享受-明基RD320U显示器
引言 作为一名有着多年JAVA开发经验的从业者,在工作过程中,显示器的重要性不言而喻。它不仅是我们与代码交互的窗口,更是影响工作效率和体验的关键因素。在多年的编程生涯中,我遇到过各种各样的问题。比如,在进行代码…...
10分钟上手DeepSeek开发:SpringBoot + Vue2快速构建AI对话系统
作者:后端小肥肠 目录 1. 前言 为什么选择DeepSeek? 本文技术栈 2. 环境准备 2.1. 后端项目初始化 2.2. 前端项目初始化 3. 后端服务开发 3.1. 配置文件 3.2. 核心服务实现 4. 前端服务开发 4.1. 聊天组件ChatWindow.vue开发 5. 效果展示及源…...
LeetCode 0624.数组列表中的最大距离:只关心最小最大值
【LetMeFly】624.数组列表中的最大距离:只关心最小最大值 力扣题目链接:https://leetcode.cn/problems/maximum-distance-in-arrays/ 给定 m 个数组,每个数组都已经按照升序排好序了。 现在你需要从两个不同的数组中选择两个整数ÿ…...
如何解决服务器端口被攻击:全面防护与快速响应
服务器端口被攻击是网络安全中常见的问题之一,尤其是当服务器暴露在公共网络上时,容易成为黑客的目标。攻击者可能通过扫描开放端口、利用漏洞或发动拒绝服务(DoS/DDoS)攻击来破坏服务器的正常运行。本文将详细介绍如何检测、防御…...
Golang深度学习
前言 在2009年,Google公司发布了一种新的编程语言,名为Go(或称为Golang),旨在提高编程效率、简化并发编程,并提供强大的标准库支持。Go语言的设计者们希望通过Go语言能够解决软件开发中的一些长期存在的问…...
Linux环境开发工具
Linux软件包管理器yum Linux下安装软件方式: 源代码安装rpm安装——Linux安装包yum安装——解决安装源、安装版本、安装依赖的问题 yum对应于Windows系统下的应用商店 使用Linux系统的人:大部分是职业程序员 客户端怎么知道去哪里下载软件࿱…...
JupyterNotebook高级使用:常用魔法命令
%%writefile test.py def Test(name):print("Test",name,"success")运行结果:就是在我们的文件目录下面创建了这个test.py文件,主要是认识一下这个里面的%%writefile表示创建新的文件,这个文件里面的内容就是上面我们定义…...
C++ Primer 类的作用域
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
【建设工程经济】2.1-2.2 经济效果评价的相关概念及指标体系
一、学前建议 学习内容主要有: ①财务评价的内容:盈利能力分析、偿债能力分析、财务可持续能力分析(财务生存能力); ②经济效果评价方法分类:确定性和不确定性评价、定量分析和定性分析、静态分析和动态分…...
如何用ollama快速布署deepseek-r1大模型
deepseek在春节期间因为特朗普的一番发言而在中国已几乎人尽皆知,热度到了连90高寿的老父亲都向我推荐这个中国产的AI大模型,而且它是开源的!我试验了下,用ollama也可以快速度安装布署deepseek-r1大模型。本想写篇文章来介绍下dee…...
50页PDF|数字化转型成熟度模型与评估(附下载)
一、前言 这份报告依据GBT 43439-2023标准,详细介绍了数字化转型的成熟度模型和评估方法。报告将成熟度分为五个等级,从一级的基础转型意识,到五级的基于数据的生态价值构建与创新,涵盖了组织、技术、数据、资源、数字化运营等多…...
机器学习实战(8):降维技术——主成分分析(PCA)
第8集:降维技术——主成分分析(PCA) 在机器学习中,降维(Dimensionality Reduction) 是一种重要的数据处理技术,用于减少特征维度、去除噪声并提高模型效率。主成分分析(Principal C…...
面试编程题
1. 请写出string类的定义,要求有构造函数,析构函数,拷贝,赋值函数。 #include <cstring> #include <algorithm>class String { public:explicit String(const char* str nullptr){if(str){str_ new char[strlen(st…...
