线性表的顺序存储

线性表的顺序存储

1.基本概念

这里写图片描述

2.设计和实现

2.1 插入元素算法

  • 判断线性表是否合法
  • 判断插入位置是否合法
  • 把最后一个元素到插入位置的元素后移一个位置
  • 将新元素插入
  • 线性表长度加1

2.2 获取元素操作

  • 判断线性表是否合法
  • 判断位置是否合法
  • 直接通过数组下标的方式获取元素

2.3 删除元素算法

  • 判断线性表是否合法
  • 判断删除位置是否合法
  • 将元素取出
  • 将删除位置后的元素分别向前移动一个位置
  • 线性表长度减1

2.4 具体代码:

  • 头文件:
#pragma
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

/*数据类型的封装--使用void类型*/
typedef void SeqList;
typedef void SeqListNode;//接受任意类型的数据元素,
                        //存放的是具体数据元素的首地址,
                        //不是直接存放数据元素

/*顺序存储各个函数*/
SeqList* SeqList_Create(int capacity);

void SeqList_Destroy(SeqList* list);

void SeqList_Clear(SeqList* list);

int SeqList_Length(SeqList* list);

int SeqList_Capacity(SeqList* list);

int SeqList_Insert(SeqList* list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);
  • 实现文件
#include "seqlist.h"

/*表头数据结构*/
typedef struct _MyStruct
{
    int length;//当前实际长度
    int capacity;//容量
    unsigned int * node;//线性表的起始位置,线性表里的每一个节点存放的是地址值,
                        //该地址是每个数据元素的起始地址,类似于Linux内核里面的链表思想
}TSeqList;

/*创建线性表*/
SeqList* SeqList_Create(int capacity)
{
    TSeqList * tmp = NULL;//表头

    tmp = (TSeqList*)malloc(sizeof(TSeqList));//为表头分配内存
    if (NULL == tmp)
    {
        printf("Sorry!\n");
        return NULL;
    }
    memset(tmp, 0, sizeof(TSeqList));//初始化表头

    /*根据容量分配内存*/
    tmp->node = (unsigned int *)malloc(sizeof(unsigned int )*capacity);
    if (tmp->node == NULL)
    {
        printf("sorry!!\n");
        return NULL;
    }

    /*初始化容量和长度*/
    tmp->capacity = capacity;
    tmp->length = 0;

    /*返回表头*/
    return tmp;
}


/*销毁线性表*/
void SeqList_Destroy(SeqList* list)
{
    TSeqList * tmp = NULL;
    /*合法性检测*/
    if (list == NULL)
    {
        return ;
    }

    tmp = (TSeqList*)list;
    /*先释放线性表*/
    if (tmp->node != NULL)
    {
        free(tmp->node);
    }
    /*再释放表头*/
    free(tmp);

    return ;
}

/*清空线性表*/
void SeqList_Clear(SeqList* list)
{
    TSeqList * tmp = NULL;
    if (list == NULL)
    {
        return ;
    }
    tmp = (TSeqList*)list;
    tmp->length = 0;//清空长度即可

    return ;
}

/*获取线性表长度*/
int SeqList_Length(SeqList* list)
{

    TSeqList * tmp = NULL;
    if (list == NULL)
    {
        return -1;
    }
    tmp = (TSeqList*)list;

    return tmp->length;
}

/*获取容量*/
int SeqList_Capacity(SeqList* list)
{

    TSeqList * tmp = NULL;
    if (list == NULL)
    {
        return -1;
    }
    tmp = (TSeqList*)list;

    return tmp->capacity;
}


/*插入元素:把数据元素的首地址放进线性表的节点*/
int SeqList_Insert(SeqList* list, SeqListNode* node, int pos)
{
    TSeqList * tmp = NULL;
    int i = 0;

    /*合法性判断*/
    if (list == NULL || node == NULL || pos < 0)
    {
        printf("argv is error\n");
        return -1;
    }

    tmp = (TSeqList*)list;

    /*线性表是否已满*/
    if (tmp->capacity <= tmp->length)
    {
        printf("is full\n");
        return -2;
    }

    /*给出的目标位置是否合理*/
    if (pos >= tmp->length)
    {
        pos = tmp->length;//容错纠正
    }

    /*元素后移*/
    for (i = tmp->length; i > pos;i--)
    {
        tmp->node[i] = tmp->node[i - 1];
    }


    tmp->node[i] = (unsigned int)node;//将数据元素首地址直接存入线性表节点中
    tmp->length++;//长度修改
    return 1;
}

/*获取指定位置的元素*/
SeqListNode* SeqList_Get(SeqList* list, int pos)
{
    TSeqList * tmp = NULL;

    if (list == NULL || pos < 0)
    {
        printf("argv is error\n");
        return NULL;
    }

    tmp = (TSeqList*)list;

    return (void *)(tmp->node[pos]);//返回数据元素的首地址
}

/*从线性表删除指定位置的数据元素*/
SeqListNode* SeqList_Delete(SeqList* list, int pos)
{
    TSeqList * tmp = NULL;
    SeqListNode * ret = NULL;
    int i = 0;
    if (list == NULL || pos < 0)
    {
        printf("argv is error\n");
        return NULL;
    }

    tmp = (TSeqList*)list;

    /*容错纠正*/
    if (pos >= tmp->length)
    {
        pos = tmp->length;
    }

    /*获取要删除的数据元素的首地址*/
    ret = (void*)(tmp->node[pos]);

    /*元素前移*/
    for (i = pos + 1; i < tmp->length; i++)
    {
        tmp->node[i - 1] = tmp->node[i];
    }

    tmp->length--;//修改长度
    return ret;//返回被删除的数据元素首地址
} 
  • 测试文件

#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 = 31;
    t2.age = 32;
    t3.age = 33;
    t4.age = 34;
    t5.age = 35;

    list = SeqList_Create(10);
    if (list == NULL)
    {
        printf("func SeqList_Create() ret :%d \n", ret);
        return;
    }

    ret = SeqList_Insert(list, (SeqListNode*)&t1, 0); //头插法
    ret = SeqList_Insert(list, (SeqListNode*)&t2, 0); //头插法
    ret = SeqList_Insert(list, (SeqListNode*)&t3, 0); //头插法
    ret = SeqList_Insert(list, (SeqListNode*)&t4, 0); //头插法
    ret = SeqList_Insert(list, (SeqListNode*)&t5, 0); //头插法

    //遍历
    for (i = 0; i<SeqList_Length(list); i++)
    {
        Teacher*  tmp = (Teacher *)SeqList_Get(list, i);
        if (tmp == NULL)
        {
            return;
        }
        printf("tmp->age:%d ", tmp->age);
    }
    int var = 190;//同时插入Teacher和int类型的数据
    ret = SeqList_Insert(list, (SeqListNode*)&var, 0); //再次证明该顺序表可以插入任意类型的数据元素
    printf("%d\n%d\n",(*(int *)SeqList_Get(list, 0)) + 1,SeqList_Length(list));

    //删除链表中的节点
    while (SeqList_Length(list) > 0)
    {
        SeqList_Delete(list, 0);
    }
    SeqList_Destroy(list);
    system("pause");
    return;
}

3. 优缺点

优点:

  • 无需为线性表中的逻辑关系增加额外的空间
  • 可以快速的获取表中合法位置的元素

缺点:

  • 插入和删除操作需要移动大量元素
  • 当线性表长度变化较大时难以确定存储空间的容量
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值