1 线性表
提示
在编程的时候要把自己的编写的代码置身于开发大型项目的子模块视角中,有利于提高自己宏观解决问题的能力,main只是你的测试。
备注
线性表定义:零个或者多个数据元素的有限序列。
线性表元素的个数定义为线性表的长度,当时,称为空表。
对于一个非空的线性表或者线性结构,具有以下特点:
- 存在唯一的一个被称作“第一个”的数据元素。
- 存在唯一的一个被称作“最后一个”的数据元素。
- 除了第一个外,结构中的每个数据元素都有一个前驱。
- 除了最后一个外,结构中的每个数据元素都有一个后继。
线性表顺序存储
线性表的顺序存储结构是指用一段地址连续的存储单元依次存储线性表的数据元素。

线性表顺序存储结构
存储结构c
/* datatype类型根据实际情况而定,这里假设为int */
typedef int datatype;
typedef struct node_st{
    datatype *data; // 数组存储数据元素,最大值为MAXSIZE。
    int last; //线性表当前长度
}sqlist;
线性表顺序存储常用操作
初始化线性表
初始化方法1-指针函数返回c
/**
 * @description: 指针函数初始化顺序线性表
 * @param {int} n
 * @return {sqlist} *
 */
sqlist *sqlist_create(int n)
{
    sqlist *me = NULL;
    //初始化存储空间
    me = malloc(sizeof(*me));
    //初始化线性表空间,按照给定的长度开辟
    me->data = malloc(sizeof(datatype)*n);
    if (me == NULL)
        return NULL;
    //线性表当前长度初始化为-1
    me->last = -1;
    return me;
}
初始化方法2-双重指针c
/**
 * @description: 不带返回值初始化顺序线性表,这里双指针**ptr的意思是对指针的地址进行改变
 * @param {sqlist} **ptr
 * @param {int} n
 * @return {*}
 */
void sqlist_create1(sqlist **ptr,int n)
{
    *ptr = malloc(sizeof(**ptr));
    (*ptr)->data = malloc(sizeof(datatype)*n);
    if (*ptr == NULL)
        return;
    (*ptr)->last = -1;
    return;
}
以上两种方式都可以对顺序线性表进行初始化,关于定义函数的注意事项参见:指针与函数 的内存泄漏章节。
顺序表插入与删除
插入算法实现顺序:
- 如果插入位置不合理,抛出异常。
- 如果线性表长度大于等于数组长度,则抛出异常或者动态增加容量。
- 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置。
- 将要插入的元素填入到第i位置。
- 表长度加1。

顺序表插入元素c
/**
 * @description: 线性表的插入
 * @param {sqlist} *me
 * @param {int} i
 * @param {datatype} *data
 * @return {*}
 */
int sqlist_insert(sqlist *me, int i, datatype *data)
{
    int j;
    //存储空间已满
    if (me->last == DATASIZE - 1)
        return -1;
    //i值不合法判断    
    if (i < 0 || i > me->last + 1)
        return -2;
    for (j = me->last; i <= j; j--)
        me->data[j + 1] = me->data[j];
        //插入位置以及之后的位置后移动1位
    me->data[i] = *data;
    me->last++;
    return 0;
}
删除算法实现思路:
- 如果删除位置不合理,抛出异常。
- 取出删除元素。
- 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置。
- 表长度减1。
 
顺序表删除元素c
/**
 * @description: 线性表某个i位置元素进行删除
 * @param {sqlist} *me
 * @param {int} i
 * @return {*}
 */
int sqlist_delete(sqlist *me, int i)
{
    int j;
    //判断i值是否合法
    if (i < 0 || i > me->last)
        return -1;
    //从删除位置开始,将后面的元素都向前移动一位
    for (j = i + 1; j <= me->last; j++)
        me->data[j - 1] = me->data[j];
    //更新线性表长度
    me->last--;
    //返回0表示删除成功
    return 0;
}
其他线性表操作
获取指定元素的位置
获取位置c
/**
 * @description: 查找  匹配元素的位置下标
 * @param {sqlist} *me
 * @param {datatype} *data
 * @return {int}
 */
int sqlist_find(sqlist *me, datatype *data)
{
    int i;
    //判断线性表是否为空
    if (sqlist_isempty == 0)
        return -1;
    //遍历线性表,查找指定元素
    for (i = 0; i < me->last; i++)
        if (me->data[i] == *data)
            return i;
    //未找到指定元素,返回-2
    return -2;
}
获取顺序表长度
/**
 * @description: 查看线性表长度
 * @param {sqlist} *me
 * @return {int}
 */
int sqlist_getnum(sqlist *me)
{
    return (me->last + 1);
}
判断顺序表是否为空表与清空
/**
 * @description: 判断线性表是否为空
 * @param {sqlist} *me
 * @return {int}
 */
int sqlist_isempty(sqlist *me)
{
    if (me->last = -1)
        return 0;
    return -1;
}
/**
 * @description: 清空线性表
 * @param {sqlist} *me
 * @return {int}
 */
int sqlist_setempty(sqlist *me)
{
    me->last = -1; 
    sqlist_destroy(me);
    return 0;
}
顺序输出顺序表
输出线性表c
/**
 * @description: 显示线性表内容
 * @param {sqlist} *me
 * @return {void}
 */
void sqlist_display(sqlist *me)
{
    int i;
    if (me->last == -1)
        return;
    for (i = 0; i <= me->last; i++)
        printf("%d ", me->data[i]);
    printf("\n");
    return;
}