线性表(List)---顺序存储结构

线性表(List)—顺序存储结构的设计与实现


线性表顺序结构的设计

线性表顺序存储结构:用一段地址连续地存储单元依次存放 线性表的数据元素。
Array

定义一个结构体用存储数据

typedef struct _tag_SeqList
{
    int Length;//长度
    int Capacity;//容量
    unsigned int **node;
}TSeqList;
  • int Capacity:表示线性表顺序分配空间的总个数【容量】。
  • int Length:表示当前顺序表存放数据的个数【当前长度】。
  • unsigned int **node:分配Capacity个连续的内存空间存放unsigned int *node ,以便接收外外部数据地址。
    struct

线性表顺序存储结构的重要算法

  • 插入元素算法 int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos)
    1.判断线性表是否合法;
    2.判断插入元素位置是否合法;
    3.要把插入第pos位的后面的位置的元素都后移一位;
    4.新元素插入;
    5.线性表当前长度(Length)加1。

  • 获取元素算法 SeqlistNode *SeqList_Get(Seqlist *list, int pos)
    1.判断线性表是否合法;
    2.判断位置是否合法;
    3.直接通过数组下标方式获取元素。

  • 删除元素算法 SeqlistNode *SeqList_Get(Seqlist *list, int pos)
    1.判断线性表是否合法;
    2.判断删除位置是否合法;
    3.将元素取出;
    4.将删除位置后的元素分别向前移动一一个位置;
    5.线性表当前长度(Length)减1。


线性表顺序结构的实现

  • SeqList.h
#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef void Seqlist;
typedef void SeqlistNode;

//创建容量为capacity的线性表
Seqlist * SeqList_Create(int capacity);

//清空线性表
void SeqList_Clear(Seqlist *list);

//销毁线性表
void SeqList_Destroy(Seqlist *list);

//获取线性表的当前长度
int SeqList_Length(Seqlist *list);

//获取线性表的容量
int SeqList_Capacity(Seqlist *list);

//向线性表pos位置插入node元素
int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos);

//将线性表pos位置的元素删除
SeqlistNode *SeqList_Delete(Seqlist *list, int pos);

//获取线性表的pos位置元素
SeqlistNode *SeqList_Get(Seqlist *list, int pos);

#endif // !_SEQLIST_H_
  • SeqList.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seqlist.h"

typedef struct _tag_SeqList
{
    int Length;//长度
    int Capacity;//容量
    unsigned int **node;
}TSeqList;

//创建容量为capacity的线性表
Seqlist * SeqList_Create(int capacity)
{
    int ret = 0;
    TSeqList *tmp = NULL;
    tmp = (TSeqList *)malloc(sizeof(TSeqList));
    if (tmp == NULL)
    {
        ret = -1;
        printf("func SeqList_Create()  malloc(sizeof(TSeqList)) err:%d\n", ret);
        return tmp;
    }

    //初始化内存空间
    memset(tmp, 0, sizeof(TSeqList));

    //根据capacity分配线性表空间容量
    tmp->node = (unsigned int **)malloc(sizeof(unsigned int *)*capacity);
    if (tmp->node == NULL)
    {
        ret = -2;
        printf("func SeqList_Create() malloc(sizeof(unsigned int *)*capacity) err:%d\n", ret);
        return tmp->node;
    }

    tmp->Capacity = capacity;
    //tmp->Length()在memset()函数中已经被初始化为0了

    return tmp;
}
//清空线性表
void SeqList_Clear(Seqlist *list)
{
    TSeqList *tlist = NULL;
    //判断线性表list是否为空
    if (list == NULL)
    {
        return;
    }

    tlist = (TSeqList *)list;
    tlist->Length = 0;

    return;
}

//销毁线性表
void SeqList_Destroy(Seqlist *list)
{
    TSeqList *tlist = NULL;
    //判断线性表list 是否为空
    if (list == NULL)
    {
        return;
    }

    tlist = (TSeqList *)list;
    //判断tlist->node是否为空
    if (tlist->node != NULL)
    {//释放tlist->node的内存空间
        free(tlist->node);
        tlist->node = NULL;
        tlist->Length = 0;
        tlist->Capacity = 0;
    }
    return ;
}

//获取线性表的长度
int SeqList_Length(Seqlist *list)
{
    int ret = 0;
    TSeqList *tlist = NULL;
    if (list == NULL)
    {
        ret = -1;
        printf("func SeqList_Length() err:%d\n", ret);
        return ret;
    }
    tlist = (TSeqList *)list;
    ret = tlist->Length;
    return ret;
}

//获取线性表的容量
int SeqList_Capacity(Seqlist *list)
{
    int ret = 0;
    TSeqList *tlist = NULL;
    if (list == NULL)
    {
        ret = -1;
        printf("func SeqList_Capacity() err:%d\n", ret);
        return ret;
    }
    tlist = (TSeqList *)list;
    ret = tlist->Capacity;
    return ret;
}

//向线性表pos位置插入元素node
int SeqList_Insert(Seqlist *list, SeqlistNode *node, int pos)
{
    int i = 0, ret = 0;
    TSeqList *tlist = NULL;
    //          ①判断线性表是否合法;
    if (list == NULL || node == NULL || pos < 0)
    {
        ret = -1;
        printf("func SeqList_Insert()  (list == NULL || node == NULL || pos < 0) err:%d\n", ret);
        return ret;
    }

    tlist = (TSeqList *)list;
    //          ②判断插入元素位置是否合法;
    if (tlist->Length >= tlist->Capacity)
    {
        ret = -2;
        printf("func SeqList_Insert()  (tlist->Length >= tlist->Capacity) err:%d\n", ret);
        return ret;
    }

    // 容错:线性表容量为20,但是length为6,用户要在第10个位置插入元素,将元素插入到了第7个位置
    if (pos > tlist->Length)
    {
        pos = tlist->Length;
    }

    //          ③要把插入第pos位的后面的位置的元素都后移一位;
    for (i = tlist->Length; i > pos; i--)
    {
        tlist->node[i] = tlist->node[i-1];
    }

    //          ④新元素插入;
    tlist->node[i] = (unsigned int*)node;

    //          ⑤线性表当前长度(Length)加1;    
    tlist->Length++;

    return ret;
}

//将线性表pos位置的元素删除
SeqlistNode *SeqList_Delete(Seqlist *list, int pos)
{
    int ret = 0, i = 0;
    TSeqList *tlist = NULL;
    SeqlistNode *tmp = NULL;
    //          ①判断线性表是否合法;
    if (list == NULL || pos < 0)
    {
        ret = -1;
        printf("func SeqList_Delete() (list == NULL || pos < 0) err:%d\n", ret);
        return tmp;
    }

    tlist = (TSeqList *)list;
    //          ②判断删除位置是否合法;
    if (pos > tlist->Length)
    {
        ret = -2;
        printf("func SeqList_Delete() (pos > tlist->Length) err:%d\n", ret);
        return tmp;
    }

    //          ③将元素取出;
    tmp = (SeqlistNode *)tlist->node[pos];

    //          ④将删除位置后的元素分别向前移动一一个位置
    for ( i = pos+1; i < tlist->Length; i++)
    {
        tlist->node[i - 1] = tlist->node[i];
    }

    //          ⑤线性表当前长度(Length)减1
    tlist->Length--;

    return tmp;
}

//获取线性表pos位置的元素
SeqlistNode *SeqList_Get(Seqlist *list, int pos)
{
    int ret = 0;
    TSeqList *tlist = NULL;
    SeqlistNode *tmp = NULL;
    //          ①判断线性表是否合法;
    if (list == NULL || pos < 0)
    {
        ret = -1;
        printf("func SeqList_Get() (list == NULL || pos < 0) err:%d\n", ret);
        return tmp;
    }

    tlist = (TSeqList *)list;
    //          ②判断位置是否合法;
    if (pos > tlist->Length)
    {
        ret = -2;
        printf("func SeqList_Get() (pos > tlist->Length) err:%d\n", ret);
        return tmp;
    }

    //          ③直接通过数组下标方式获取元素  
    tmp = tlist->node[pos];

    return tmp;
}
  • SeqList集成测试框架
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "seqlist.h"

typedef struct Teacher
{
    int age;
    char name[64];
}Teacher;

void main()
{
    int ret = 0, i = 0;
    Seqlist *list = NULL;

    Teacher t1,t2,t3,t4,t5;
    t1.age = 11;
    t2.age = 22;
    t3.age = 33;
    t4.age = 44;
    t5.age = 55;
    strcpy(t1.name, "t1");
    strcpy(t2.name, "t2");
    strcpy(t3.name, "t3");
    strcpy(t4.name, "t4");
    strcpy(t5.name, "t5");

    list = SeqList_Create(10);                   //创建一个容量为10的线性表
    if (list == NULL)                                    //判断线性表是否创建成功
    {
        printf("func SeqList_Create() err\n");
        return;
    }

    ret = SeqList_Capacity(list);                        //获取线性表容量
    printf("The Capacity of List is %d\n", ret);

    ret = SeqList_Insert(list, (SeqlistNode *)&t1, 0);   //向线性中插入元素
    if (ret != 0)                                        //判断是否插入成功
    {
        printf("func SeqList_Insert() err: %d\n", ret);
        return;
    }

    ret = SeqList_Insert(list, (SeqlistNode *)&t2, 1);   //向顺序表中插入元素
    if (ret != 0)                                        //判断是否插入成功
    {
        printf("func SeqList_Insert() err: %d\n", ret);
        return;
    }

    ret = SeqList_Insert(list, (SeqlistNode *)&t3, 2);   //向顺序表中插入元素
    if (ret != 0)                                        //判断是否插入成功
    {
        printf("func SeqList_Insert() err: %d\n", ret);
        return;
    }

    ret = SeqList_Insert(list, (SeqlistNode *)&t4, 3);   //向顺序表中插入元素
    if (ret != 0)                                        //判断是否插入成功
    {
        printf("func SeqList_Insert() err: %d\n", ret);
        return;
    }

    ret = SeqList_Insert(list, (SeqlistNode *)&t5, 4);   //向顺序表中插入元素
    if (ret != 0)                                        //判断是否插入成功
    {
        printf("func SeqList_Insert() err: %d\n", ret);
        return;
    }

    ret= SeqList_Length(list);                           //获取线性表当前长度
    printf("The Length of SeqList is %d\n", ret);          

    printf("Get Elements of Seqlist: \n");
    for(i=0;i<SeqList_Length(list);i++)
    {
        Teacher *tmp = (Teacher *)SeqList_Get(list, i);  //获取线性表第i个位置节点 
        if (tmp == NULL)                                 //获取节点是否成功
        {
            printf("func SeqList_Get() err\n");
            return;
        }
        printf("tmp->name:%s\t tmp->age:%d\n", tmp->name, tmp->age);
    }
    printf("Delete Elements of SeqList:\n");
    while (SeqList_Length(list))
    {
        Teacher *tmp = (Teacher *)SeqList_Delete(list, 0);//删除线性表第0个位置节点 
        if (tmp == NULL)                                 //删除节点是否成功
        {
            printf("func SeqList_Get() err\n");
            return;
        }
        printf("tmp->name:%s\t tmp->age:%d\n", tmp->name, tmp->age);
    }

    SeqList_Clear(list);                                 //清空顺序表
    SeqList_Destroy(list);                               //销毁顺序表

    return;
}
  • 运行结果
    Result_SeqList
线性表插入一个元素的顺序存储实现可以通过以下步骤完成: 1. 首先,判断线性表是否已满。因为顺序存储需要预先分配一定大小的内存空间来存储元素,如果线性表已满,则无法插入新元素。 2. 如果线性表未满,则需要确定插入的位置。可以根据插入位置的索引来确定元素应该插入的位置。 3. 将插入位置之后的所有元素后移一位,为新元素腾出位置。 4. 将新元素插入到插入位置处。 5. 最后,更新线性表的元素个数。 这样,线性表的插入操作就完成了。通过顺序存储,我们可以在常数时间内完成插入操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [线性表-顺序存储.c](https://download.csdn.net/download/BaiRuichang/12319228)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [数据结构(一)——线性表顺序存储原理及实现](https://blog.csdn.net/hml111666/article/details/122848223)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值