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

顺序存储的原理:
1.首先,什么是线性表?顾名思义,线性表就是由零个或多个数据元素的有限序列。
2.所谓顺序存储,就是在存储器中分配一段连续的存储空间,逻辑上相邻的数据元素,其物理存储地址也是相邻的。
3.应该注意的是,表的长度未必与容量相同,表的长度要小于等于表的容量。
4.在顺序存储中,只要确定了线性表在存储空间里的起始位置,线性表中的任意元素就都可随机存取,所以线性表的顺序存储结构是一种随机存取的结构,在高级语言中,顺序存储就是用数组来实现的。
5.在顺序存储中,系统不需要为表元素之间的逻辑关系增加额外的存储空间,而且在存取元素时,它可以根据给出的下标快速计算出元素的存储地址,从而达到随机读取的目的。
6.一般,不建议在顺序表中插入或删除元素,因为效率会很低。
顺序存储的实现:
1.创建顺序表:
首先需要创建一个头结点来存放顺序表的长度,大小和地址等信息,然后再创建顺序表,同时将顺序表的地址保存在头结点中:
具体实现思路如下:
(1)定义一个struct来保存顺序表信息;
(2)为头结点分配空间;
(3)为顺序表分配空间,将顺序表空间地址保存在头结点中;
(4)将头结点地址返回给调用者。
代码实现如下:

typedef struct _tag_SeqList //头结点,记录表的信息
{
    int capacity; //表容量
    int length;  //表长度
    int *node; //node[capacity],为指针数组
}TSeqList;

//创建顺序表
SeqList *SeqList_Create(int capacity) //返回值为SeqList *类型,即顺序表的地址
{
    int ret;
    TSeqList *temp = NULL;//创建一个头结点
    temp = (TSeqList*)malloc(sizeof(TSeqList)); //为头结点分配空间
    if (temp == NULL)
    {
        ret = 1;
        printf("func SeqList_Create() error:%d\n",ret);
        return NULL;
    }
    memset(temp, 0, sizeof(TSeqList));
    temp->capacity = capacity;
    temp->length = 0;
    temp->node = (int *)malloc(sizeof(void*)*capacity);//分配一个指针数组
    if (temp->node == NULL)
    {
        ret = 2;
        printf("func SeqList_Create() error:%d\n",ret);
        return NULL;
    }
    return temp; //将分配好的顺序表的地址返回
}

2.求顺序表容量:
在实现顺序表时,一般将顺序表信息保存在头结点中,因此求顺序表容量时,可以直接从头结点中获取。
代码实现如下:

int SeqList_Capacity(SeqList *List)
{
    TSeqList *temp = NULL;
    if (list == NULL)
    {
        return;
    }
    temp = (TSeqList *)list;
    return temp->capacity;
}

3.求顺序表长度:
和求顺序表的容量一样,求顺序表大小也是从头结点中获取信息
代码实现如下:

int SeqList_Length(SeqList *list)
{
    TSeqList *temp = NULL;
    if (list == NULL)
    {
        return;
    }
    temp = (TSeqList *)list;
    return temp->length;
}

4.插入元素:
增删改修是数据结构的核心操作,每种数据结构都要实现这几种最基本的操作。
当顺序表已满时,表中的元素无法向后移动,需要作出特别处理(例如不插入,或者新开辟一块更大的空间来存储这些元素)。
当插入的位置在空闲区域时,需要作出相应处理。
代码实现如下:

int SeqList_Insert(SeqList *list, SeqListNode* node, int pos)//参数为顺序表地址,要插入的元素地址,插入位置
{
    int i = 0;
    TSeqList *temp = NULL;
    if (list == NULL || node == NULL)
    {
        return -1;
    }
    temp = (TSeqList*)list;
    //如果顺序表已满
    if (temp->length >= temp->capacity)//如果顺序表为空,或者结点为空
    {
        return -2;
    }
    //容错 
    if (pos > temp->length) //如果给出的pos在长度后,即中间有空余,就修正到最后一个元素后面
    {
        pos = temp->length;
    }
    for (i = temp->length; i > pos; i--) //将插入位置的元素依次后移
    {
        temp->node[i] = temp->node[i - 1];
    }
    temp->node[i] = (int)node; //然后在腾出来位置插入新元素结点
    temp->length++; //插入成功后,长度加1
    return 0;
}

5.删除元素:
从顺序表中删除某个元素,则将元素删除后,需要将后面的元素依次向前移动来补齐空位。
代码实现如下:

SeqList *SeqList_Delete(SeqList *list, int pos)
{
    int  i = 0;
    TSeqlist *tlist = NULL;
    SeqListNode *temp = NULL;
    tlist = (TSeqList *)list;
    if (list == NULL || pos < 0 || pos >= tlist->capacity)
    {
        printf("SeqList_Delet() error\n");
        return NULL;
    }
    temp = (SeqlistNode *)tlist->node[pos];
    for (i = pos + 1; i < tlist->length; i++)
    {
        tlist->node[i - 1] = tlist->node[i];
    }
    tlist->length--;
    return temp;
}

6.查找某个位置上的元素:
因为顺序表在底层是以数组来实现的,每个存储单元都有索引标注,要查找某个位置上的元素,直接按索引来查找即可。
代码实现如下:

SeqList *SeqList_Get(SeqList *list, int pos)
{
    TSeqList *tlist = NULL;
    SeqListNode *temp = NULL;
    tlist = (TSeqList *)list;
    if (list == NULL || pos < 0 || pos >= tlist->capacity)
    {
        printf("SeqList_Get() error\n");
        return NULL;
    }
    temp = (SeqListNode *)tlist->node[pos]; //将表中pos位置的结点指针赋给temp
    return temp;
}

7.清空表:
清空顺序表是将表中的内容全部置为0.
代码实现如下:

void SeqList_Clear(SeqList* list)
{
    TSeqList *temp = NULL;
    if (list == NULL)
    {
        return;
    }
    temp = (TSeqList *)List;
    temp->length = 0;
    memset(temp->node, 0, (temp->capacity*sizeof(void *)));//将顺序表全部归0
    return;
}

8.销毁表:
销毁顺序表是将表整个销毁。
代码实现如下:

void SeqList_Destory(SeqList *list)
{
    TSeqList*temp = NULL;
    if (list == NULL) //如果顺序表为空
    {
        return;
    }
    temp = (TSeqList *)list;
    if (temp->node != NULL)
    {
        free(temp->node);  //先释放头结点中的指针数组
    }
    free(temp);   //再释放头结点
    return;
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值