顺序表(线性表的顺序存储)

1 概念

线性表:数据和数据之间的一对一的关系

顺序存储:需要在内存中开辟一块连续的空间存储数据,一般使用数组来存储数据,

为了方便对数组进行操作,通常会定义一个变量来保存最后一个元素的下标

2 对顺序表的操作

2.1 创建一个空的顺序表

#include <stdio.h>
#include <stdlib.h>

//对数据的类型进行取别名,方便对表中的数据类型进行修改,
//提高代码的拓展性
typedef int DataType;

//定义一个结构体
typedef struct{
    DataType data[32];
    int pos;
}seqlist;

//创建一个空的顺序表
seqlist *SeqlistCreate()
{
    //在堆区申请空间
    seqlist *st = (seqlist *)malloc(sizeof(seqlist));
    //初始化,标识当前顺序表中没有元素
    st->pos = -1;

    //返回顺序表的首地址
    return st;
}

2.2 判断顺序表是否为满

//判断顺序表是否为满
//如果为满,函数返回1,否则返回0
int SeqlistIsFull(seqlist *st)
{
#if 0
    if(st->pos == N - 1)
    {
        return 1;
    }
    else
    {
        return 0;
    } 
#endif
    return st->pos == N - 1 ? 1 : 0;
}

2.3 插入数据

//插入数据(每调用一次插入一个数据)
void SeqlistInsert(seqlist *st, DataType value)
{
    //插入数据之前先判断当前顺序表是否为满
    if(SeqlistIsFull(st) == 1)
    {
        printf("插入失败,顺序表为满\n");
        return ;
    }

    //保存最后一个元素的变量pos自增
    st->pos++;
    //将数据插入到pos位置的地方
    st->data[st->pos] = value;

    printf("插入成功\n");

    return ;
}

2.4 遍历顺序表

//遍历顺序表
void SeqlistPrint(seqlist *st)
{
    int i;
    for(i = 0; i <= st->pos; i++)
    {
        printf("%d ", st->data[i]);
    }

    putchar(10);
}

2.5 判断顺序表是否为空

//判断顺序表是否为空
//如果为空返回1,失败返回0
int SeqlistIsEmpty(seqlist *st)
{
    return st->pos == -1 ? 1 : 0;
}

2.6删除数据并返回删除的数据

//删除数据并返回删除的数据
DataType SeqlistDelete(seqlist *st)
{
    //在删除数据之前判断是否为空
    if(SeqlistIsEmpty(st) == 1)
    {
        printf("删除失败,顺序表为空了\n");
        return (DataType)-1;
    }

    DataType value = st->data[st->pos];
    st->pos--;

    printf("删除成功\n");

    return value;
}

2.7 按照位置插入数据

//按照位置插入数据
void SeqlistInserByPos(seqlist *st, int p, DataType value)
{
    int i;

    //判断顺序表是否为满
    if(SeqlistIsFull(st) == 1)
    {
        printf("插入失败,顺序表为满\n");
        return ;
    }

    //判断插入数据的位置是否合适
    if(p < 0 || p > st->pos + 1)
    {
        printf("插入失败,插入的位置有误\n");
        return ;
    }

    //如果插入数据的位置刚好是原本pos+1,则直接插入即可
    if(p == st->pos + 1)
    {
        st->data[p] = value;
        st->pos++;
    }
    else
    {
        //将p之后的数据依次向上移动
        for(i = st->pos; i >= p; i--)
        {
            st->data[i+1] = st->data[i];        
        }

        //将插入的数据放在p位置
        st->data[p] = value;

        st->pos++;
    }

    printf("按照位置插入成功\n");
}

2.8 按照位置删除数据,返回删除的数据

//按照位置删除数据,返回删除的数据
DataType SeqlistDeleteByPos(seqlist *st, int p)
{
    //判断顺序表是否为空
    if(SeqlistIsEmpty(st) == 1)
    {
        printf("删除失败,顺序表为空\n");
        return (DataType)-1;
    }

    //判断删除数据的位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("删除失败,删除的位置有误\n");
        return (DataType)-1;
    }
    //将要删除的数据保存一下
    DataType value = st->data[p];
    //将p往上的数据向下移动
    int i;
    for(i = p; i < st->pos; i++)
    {
        st->data[i] = st->data[i+1];
    }

    st->pos--;

    printf("按照位置删除数据成功\n");
    return value;
}

2.9 按照数据修改数据

//按照数据修改数据
void SeqlistUpdateByData(seqlist *st, DataType OldValue, DataType NewValue)
{
    //循环对比每一个数据,如果找到将其改成新的数据
    int i;
    int flags = 0;
    for(i = 0; i <= st->pos; i++)
    {
        if(st->data[i] == OldValue)
        {
            st->data[i] = NewValue;
            flags = 1;
        }
    }

    if(flags == 0)
    {
        printf("修改失败,%d不存在\n", OldValue);
    }
    else
    {
        printf("按照数据修改数据成功\n");
    }
}

2.10 按照位置修改数据

//按照位置修改数据
void SeqlistUpdateByPos(seqlist *st, int p, DataType value)
{
    //判断位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("修改失败,位置有误\n");
        return ;
    }

    st->data[p] = value;
    printf("按照位置修改数据成功\n");
}

2.11 按照数据查找位置

//按照数据查找位置
int SeqlistSearchPos(seqlist *st, DataType value)
{
    int i;
    for(i = 0; i <= st->pos; i++)
    {
        if(st->data[i] == value)
        {
            printf("按照数据查找位置成功\n");
            return i;
        }
    }

    printf("查找失败,数据%d不存在\n", value);
    return -1;
}

2.12 按照位置查找数据

//按照位置查找数据
DataType SeqlistSearchData(seqlist *st, int p)
{
    //判断位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("修改失败,位置有误\n");
        return (DataType)-1;
    }

    printf("按照位置查找数据成功\n");
    return st->data[p];
}

3.整体代码

#include <stdio.h>
#include <stdlib.h>

#define N 32

//对数据的类型进行取别名,方便对表中的数据类型进行修改,
//提高代码的拓展性
typedef int DataType;

//定义一个结构体
typedef struct{
    DataType data[N];
    int pos;
}seqlist;

//创建一个空的顺序表
seqlist *SeqlistCreate();
//判断顺序表是否为满
int SeqlistIsFull(seqlist *st);
//插入数据(每调用一次插入一个数据)
void SeqlistInsert(seqlist *st, DataType value);
//遍历顺序表
void SeqlistPrint(seqlist *st);
//删除数据并返回删除的数据
DataType SeqlistDelete(seqlist *st);
//删除数据并返回删除的数据
DataType SeqlistDelete(seqlist *st);
//按照位置插入数据
void SeqlistInserByPos(seqlist *st, int p, DataType value);
//按照位置删除数据,返回删除的数据
DataType SeqlistDeleteByPos(seqlist *st, int p);
//按照数据修改数据
void SeqlistUpdateByData(seqlist *st, DataType OldValue, DataType NewValue);
//按照位置修改数据
void SeqlistUpdateByPos(seqlist *st, int p, DataType value);
//按照数据查找位置
int SeqlistSearchPos(seqlist *st, DataType value);
//按照位置查找数据
DataType SeqlistSearchData(seqlist *st, int p);
int main(int argc, char const *argv[])
{
    seqlist *s1 = SeqlistCreate();
    SeqlistInsert(s1, 100);
    SeqlistInsert(s1, 200);
    SeqlistInsert(s1, 300);
    SeqlistInsert(s1, 400);
    SeqlistInsert(s1, 500);
    SeqlistInsert(s1, 600);
    SeqlistPrint(s1);

    DataType del_val;
    del_val = SeqlistDelete(s1);
    printf("删除的元素是%d\n", del_val);
    SeqlistPrint(s1);

    SeqlistInserByPos(s1, 2, 888);
    SeqlistPrint(s1);

    DataType del_val1;
    del_val1 = SeqlistDeleteByPos(s1, 2);
    printf("第2个位置删除的元素是%d\n", del_val1);
    SeqlistPrint(s1);

    SeqlistUpdateByData(s1, 300, 999);
    SeqlistPrint(s1);

    SeqlistUpdateByPos(s1, 2, 300);
    SeqlistPrint(s1);

    int p;
    p = SeqlistSearchPos(s1, 300);
    printf("数据300的位置是%d\n", p);

    DataType data1;
    data1 = SeqlistSearchData(s1, 2);
    printf("位置2的数据是%d\n", data1);

    return 0;
}

//需要将每一个功能封装成函数,这样调用起来更加方便
//创建一个空的顺序表
seqlist *SeqlistCreate()
{
    //在堆区申请空间
    seqlist *st = (seqlist *)malloc(sizeof(seqlist));
    //初始化,标识当前顺序表中没有元素
    st->pos = -1;

    printf("顺序表创建成功\n");

    //返回顺序表的首地址
    return st;
}

//判断顺序表是否为满
//如果为满,函数返回1,否则返回0
int SeqlistIsFull(seqlist *st)
{
#if 0
    if(st->pos == N - 1)
    {
        return 1;
    }
    else
    {
        return 0;
    } 
#endif
    return st->pos == N - 1 ? 1 : 0;
}


//插入数据(每调用一次插入一个数据)
void SeqlistInsert(seqlist *st, DataType value)
{
    //插入数据之前先判断当前顺序表是否为满
    if(SeqlistIsFull(st) == 1)
    {
        printf("插入失败,顺序表为满\n");
        return ;
    }

    //保存最后一个元素的变量pos自增
    st->pos++;
    //将数据插入到pos位置的地方
    st->data[st->pos] = value;

    printf("插入成功\n");

    return ;
}

//遍历顺序表
void SeqlistPrint(seqlist *st)
{
    int i;
    for(i = 0; i <= st->pos; i++)
    {
        printf("%d ", st->data[i]);
    }

    putchar(10);

    printf("顺序表遍历成功\n\n");
}

//判断顺序表是否为空
//如果为空返回1,失败返回0
int SeqlistIsEmpty(seqlist *st)
{
    return st->pos == -1 ? 1 : 0;
}

//删除数据并返回删除的数据
DataType SeqlistDelete(seqlist *st)
{
    //在删除数据之前判断是否为空
    if(SeqlistIsEmpty(st) == 1)
    {
        printf("删除失败,顺序表为空了\n");
        return (DataType)-1;
    }

    DataType value = st->data[st->pos];
    st->pos--;

    printf("删除成功\n");

    return value;
}

//按照位置插入数据
void SeqlistInserByPos(seqlist *st, int p, DataType value)
{
    int i;

    //判断顺序表是否为满
    if(SeqlistIsFull(st) == 1)
    {
        printf("插入失败,顺序表为满\n");
        return ;
    }

    //判断插入数据的位置是否合适
    if(p < 0 || p > st->pos + 1)
    {
        printf("插入失败,插入的位置有误\n");
        return ;
    }

    //如果插入数据的位置刚好是原本pos+1,则直接插入即可
    if(p == st->pos + 1)
    {
        st->data[p] = value;
        st->pos++;
    }
    else
    {
        //将p之后的数据依次向上移动
        for(i = st->pos; i >= p; i--)
        {
            st->data[i+1] = st->data[i];        
        }

        //将插入的数据放在p位置
        st->data[p] = value;

        st->pos++;
    }

    printf("按照位置插入成功\n");
}

//按照位置删除数据,返回删除的数据
DataType SeqlistDeleteByPos(seqlist *st, int p)
{
    //判断顺序表是否为空
    if(SeqlistIsEmpty(st) == 1)
    {
        printf("删除失败,顺序表为空\n");
        return (DataType)-1;
    }

    //判断删除数据的位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("删除失败,删除的位置有误\n");
        return (DataType)-1;
    }
    //将要删除的数据保存一下
    DataType value = st->data[p];
    //将p往上的数据向下移动
    int i;
    for(i = p; i < st->pos; i++)
    {
        st->data[i] = st->data[i+1];
    }

    st->pos--;

    printf("按照位置删除数据成功\n");
    return value;
}

//按照数据修改数据
void SeqlistUpdateByData(seqlist *st, DataType OldValue, DataType NewValue)
{
    //循环对比每一个数据,如果找到将其改成新的数据
    int i;
    int flags = 0;
    for(i = 0; i <= st->pos; i++)
    {
        if(st->data[i] == OldValue)
        {
            st->data[i] = NewValue;
            flags = 1;
        }
    }

    if(flags == 0)
    {
        printf("修改失败,%d不存在\n", OldValue);
    }
    else
    {
        printf("按照数据修改数据成功\n");
    }
}

//按照位置修改数据
void SeqlistUpdateByPos(seqlist *st, int p, DataType value)
{
    //判断位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("修改失败,位置有误\n");
        return ;
    }

    st->data[p] = value;
    printf("按照位置修改数据成功\n");
}

//按照数据查找位置
int SeqlistSearchPos(seqlist *st, DataType value)
{
    int i;
    for(i = 0; i <= st->pos; i++)
    {
        if(st->data[i] == value)
        {
            printf("按照数据查找位置成功\n");
            return i;
        }
    }

    printf("查找失败,数据%d不存在\n", value);
    return -1;
}

//按照位置查找数据
DataType SeqlistSearchData(seqlist *st, int p)
{
    //判断位置是否合适
    if(p < 0 || p > st->pos)
    {
        printf("修改失败,位置有误\n");
        return (DataType)-1;
    }

    printf("按照位置查找数据成功\n");
    return st->data[p];
}

4.扩展用法

1、删除重复数据(将先出现的数据与后面的数据对比,如果有重复的将后面的数据删除)

s1:1 2 2 1 1 3 4 3 2 4 5 3 4 5 4 1

......

s1:1 2 3 4 5

void SeqlistDeleteRepaet(seqlist *st)
{
    int i, j;
    for(i = 0; i < st->pos; i++)
    {
        //将i位置的数据与后面每一个位置的数据进行对比
        for(j = i + 1; j <= st->pos; j++)
        {
            //如果值一样,将后面j位置的数据删除
            if(st->data[i] == st->data[j])
            {
                //按照j位置删除数据
                SeqlistDeleteByPos(st, j);

                //j--的目的是为了防止删除位置的数据不做比较
                j--;
            }
        }
    }
}

2、合并表(将s2里面与s1不一样的数据保存在s1的后面)

s1:1 2 3 4 5

s2:1 3 5 7 9

......

s1:1 2 3 4 5 7 9

void SeqlistUnion(seqlist *s1, seqlist *s2)
{
    //循环拿去每一个s2的数据与s1的数据进行对比
    int i;
    for(i = 0; i <= s2->pos; i++)
    {
        //调用按照数据查找位置函数,将s2的数据在s1中找位置
        //如果返回值等于-1,说明s1中没有s2这个数据
        if(SeqlistSearchPos(s1, s2->data[i]) == -1)
        {
            SeqlistInsert(s1, s2->data[i]);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小徐的记事本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值