当前位置: 首页 > news >正文

《C语言动态顺序表:从内存管理到功能实现》

1.顺序表

1.1 概念

  •  顺序存储的线性表,叫顺序表。

1.2顺序表存放的实现方式

  • 可以使用数组存储数据,可以实现逻辑上相连,物理内存上也相连。
  • 也可以使用malloc在堆区申请一片连续的空间,存放数据,实现逻辑上相连,物理内存上也相连。

1.3 顺序表的组成

  • 需要一片连续的空间,存放数据。 可以是数组,也可以是连续堆区空间
  • 还需要一个变量来记录当前顺序表的长度。(已存放的元素个数)

1.5 对顺序表长度的解析

  • 顺序表的长度能够表示顺序表中实际使用的元素个数
  • 也能够表示数组中第一个没有存放数据元素的数组元素下标
  • 要遍历整个顺序表时,顺序表的长度是最大上限

1.6 顺序表结构体类型

#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 类型,并赋值给指针 S
    seq_p S = (seq_p)malloc(sizeof(seq_list));
    // 检查内存分配是否成功
    if(S == NULL)
    {
        // 若分配失败,输出错误信息并返回 NULL
        printf("空间申请失败\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)
    {
        // 若为空,输出错误信息并返回 -1
        printf("入参为空\n");
        return -1;
    }
    // 判断顺序表的长度是否为 0
    // 如果长度为 0,说明顺序表为空,返回 1
    // 如果长度不为 0,说明顺序表不为空,返回 0
    return 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)
    {
        // 若为空,输出错误信息并返回 -1
        printf("入参为空\n");
        return -1;
    }
    // 判断顺序表是否已满
    // 通过比较顺序表当前元素个数 S->len 和最大容量 MAX
    // 如果两者相等,说明顺序表已满,返回 1
    // 如果不相等,说明顺序表未满,返回 0
    return 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 就可以了
    // 顺序表长度自增
    // 插入新元素后,顺序表的长度加 1
    S->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;
    // 插入新元素后,顺序表长度加 1
    S->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];
    }
    // 删除元素后,顺序表长度减 1
    S->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;
    // 顺序表的长度加 1
    S->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];
    }
    // 顺序表长度减 1
    S->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[])
{
    // 调用创建顺序表函数,创建一个顺序表并将其指针赋值给 S
    seq_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 函数在顺序表尾部插入元素 66
    inser_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 个位置插入元素 99
    insert_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 函数释放顺序表所占用的内存,并将指针置为 NULL
    free_seq(&S);
    // 打印顺序表指针 S 的值,此时应为 NULL
    printf("%p\n", S);

    return 0;
}

4. 全局函数声明

4.1代码功能概述

        定义一个名为 seq_list.h 的头文件,它定义了顺序表的相关数据结构和操作函数的声明,用于实现顺序表的基本功能,如创建、插入、删除、判空、判满等操作。

4.2实现操作步骤

  • 头文件保护:使用 #ifndef#define 和 #endif 防止头文件被重复包含。
  • 包含必要的头文件:包含了 stdio.hstring.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$ 

相关文章:

  • python包的管理
  • 图论- Dijkstra算法
  • 【Java】ArrayList与LinkedList的性能对比深度解析
  • 循环队列知识点及习题
  • 1-8 gitee码云的注册与使用
  • 软件测试之黑盒测试与白盒测试
  • android设置添加设备QR码信息
  • 用大模型学大模型05-线性回归
  • 全面理解-c++中的内存布局
  • visutal studio 2022使用qcustomplot基础教程
  • ROS2 话题通信
  • 算法题(68):路径总和
  • 算法244(力扣136)反转字符串
  • mysql和minio
  • C语言中的文件
  • YOLOV8的学习记录(三) 训练各种模型所使用的数据格式区别
  • Farewell Go,Hello AI:是时候说再见了
  • AWS Fargate 部署流程图及说明
  • 劳力士(Rolex):蚝式恒动(Oyster Perpetual),潜航者(Submariner)和宇宙计型迪通拿(Daytona)中英双语
  • Vue.js 配置 Babel、Webpack 和 ESLint
  • 北京韩美林艺术馆党支部书记郭莹病逝,终年40岁
  • 外企聊营商|上海仲裁:化解跨国企业纠纷的“上海路径”
  • 嫩黑线货物列车脱轨致1名路外人员死亡,3人被采取刑事强制措施
  • 淄博一酒店房间内被曝发现摄像头,当地警方已立案调查
  • 四川内江警方通报一起持刀伤人致死案:因车辆停放引起,嫌犯被抓获
  • 视频丨中国海警成功救助8名外籍遇险渔民,韩方向中方致谢