数据结构——顺序表

顺序表的简单实现

抽象数据类型 ADT 线性表——顺序表(SequenceList)
特点
  1. 线性表的数据元素是一个集合{a_1, a_2, a_3, …, a_n},数据元素的类型:DataType(int, char, 自定义…)
  2. 存在唯一一个被称作“第一个”的数据元素
  3. 存在唯一一个被称作“最后一个”的数据元素
  4. 除了第一个元素a_1外,每个元素有且只有一个直接的前驱元素
  5. 除了最后一个元素a_n外,每个元素有且只有一个直接的后继元素
  6. 每个数据元素之间是一对一的关系
基本操作的函数名称及参数:
Operation
    //初始化线性表:创建一个空的线性表List
    InitList(*List)    //使用指针进行值的操作
    //在线性表List的index下标处插入元素elem
    InsertElement(*List, index, elem)
    //删除线性表List中下标为index的元素,并返回删除元素的指针e
    DeleteElement(*List, index, *elem)
    //在线性表List中查找是否存在数据元素e,存在则返回该元素在表中的下标,不存在返回-1
    ExsitElement(*List, elem)
    //返回线性表的长度
    GetLength(*List)
    //判断线性表是否为空
    IsEmpty(*List)
    //清空线性表
    ClearList(*List)
    //返回线性表中下标为index的数据元素
    GetElement(*List, index, *elem)
endADT
一、准备数据
  • 描述线性表的顺序存储结构需要三个属性:
    • 存储空间的起始位置
    • 线性表的最大存储容量
    • 线性表的当前长度
(一)定义步骤
1. 定义线性表的最大存储空间和相关数据
#define MAX_SIZE 255
#define TRUE 1
#define FALSE 0
#define NO_FOUND -1
2.线性表里需要有统一类型的元素集合
typedef int ElemType;
typedef struct {
        int id;
        char * name;
}ElemType;
3.定义顺序表结构
typedef struct{
    ElemType datas[MAX_SIZE];
    int length;
}SeqList;
(二)具体函数实现
1.初始化
void InitList(SeqList * seqList, ElemType * elemArray, int length)
{
    if(length > MAX_SIZE){
        printf("超出了顺序表的最大容量,初始化失败!");
        return;
    }
    seqList->length = 0;
    for (int i = 0; i < length; ++i) {
        //每次循环都在下标为i的位置插入一个元素
        InsertElement(seqList, i, elemArray[i]);
    }
}
2.插入元素
void InsertElement(SeqList * seqList, int index, ElemType element)
{
    if(seqList->length + 1 > MAX_SIZE){
        printf("顺序表已满,插入元素失败!\n");
        return;
    }
    if(index < 0 || index > MAX_SIZE - 1){
        printf("只能在允许的范围内插入元素[0, %d]", MAX_SIZE - 1);
        return;
    }
    if(index > seqList->length){
        printf("下标超过顺序的当前长度,无法插入!");
        return;
    }
    //操作
    for (int i = seqList->length - 1; i >= index; i--) {
        seqList->data[i + 1] = seqList->data[i];
    }
    seqList->data[index] = element;
    seqList->length++;
}

应当完成的操作

  • 验证插入操作后元素空间是否超过最大空间
  • index 的值是否合法,index ∈ [0, MAX_SIZE-1]
  • 插入的index在 length 之内
  • 从第length-1的下标开始,到index为止,前面一个元素赋值给后一个元素
  • 将要插入的值赋值给第index个元素
  • 顺序表长度+1
3.查找元素
ElemType * GetElement(SeqList * seqList, int index)
{
    //1、判断顺序表是否为空
    if(IsEmpty(seqList) == TRUE){
        printf("顺序表为空,查找失败!\n");
        return NULL;
    }
    //2、判断下标是否越界
    if(index < 0 || index >= seqList->length){
        printf("下标越界,无法找到对应的元素\n");
        return NULL;
    }
    //3、查找
    ElemType * find_elem = &seqList->data[index];
    return find_elem;
}
4.删除元素
ElemType * DeleteElement(SeqList * seqList, int index)
{
    //1、判断顺序表是否为空
    if(IsEmpty(seqList) == TRUE){
        printf("顺序表为空,删除失败!\n");
        return NULL;
    }
    //2、判断下标是否越界
    if(index < 0 || index >= seqList->length){
        printf("下标越界,无法删除该元素\n");
        return NULL;
    }
    //3、找到对应下标的元素,将其保存以便返回
    ElemType * del_elem = (ElemType*) malloc(sizeof(ElemType));
    //定义查找方法,以副本的方式保存将要删除的元素
    *del_elem = *GetElement(seqList, index);
    //4、删除对应下标的元素,从index开始,到length-1为止,后面的元素覆盖前面的元素
    for (int i = index; i < seqList->length; ++i) {
        seqList->data[i] = seqList->data[i+1];
    }
    //5、顺序表的长度-1
    seqList->length--;
    return del_elem;
}

应当完成的操作

  • 判断顺序表是否为空
  • 判断下标是否越界
  • 找到对应下标的元素,将其保存以便返回
  • 删除对应下标的元素,从index开始,到length-1为止,后面的元素覆盖前面的元素
  • 顺序表的长度-1
5.顺序表的其他操作
//判空
int IsEmpty(SeqList * seqList)
{
    return GetLength(seqList) == 0 ? TRUE : FALSE;
}

//返回顺序表的长度
int GetLength(SeqList * seqList)
{
    return seqList == 0 ? 0 : seqList->length;
}

//打印
void PrintList(SeqList * seqList)
{
    int len = seqList->length;
    for (int i = 0; i < len; ++i) {
        if(i == 0){
            printf("顺序表中的元素有:{ [%d, %s],", seqList->data[i].id, seqList->data[i].name);
        } else if(i == (len - 1)){
            printf("[%d, %s] }\n", seqList->data[i].id, seqList->data[i].name);
        } else{
            printf("[%d, %s],", seqList->data[i].id, seqList->data[i].name);
        }
    }
}

//清空顺序表
void ClearList(SeqList * seqList)
{
    if(seqList == NULL)
        return;
    seqList->length = 0;
}

//是否存在
int ExistElement(SeqList * seqList, ElemType * elem)
{
    //1、判断顺序表是否为空
    if(IsEmpty(seqList) == TRUE){
        printf("顺序表为空,不存在该元素!\n");
        return -1;
    }
    //2、查找
    int len = GetLength(seqList);
    for (int i = 0; i < len; ++i) {
        if((elem->id == seqList->data[i].id) && elem->name == seqList->data[i].name){
            return i;
        }
    }
    return NO_FOUND;
}
(三)测试代码
1.测试数据
ElemType array[] = {
        {1, "辉夜"},
        {2, "羽衣"},
        {3, "宇智波斑"},
        {4, "羽村"},
        {5, "漩涡鸣人"},
        {6, "宇智波佐助"}
};
2.测试函数
void testSeqList()
{
    SeqList seqList;
    InitList(&seqList, array, sizeof(array) / sizeof(array[0]));
    PrintList(&seqList);
    printf("顺序表的长度是:%d\n", GetLength(&seqList));

    ElemType person = array[0];
    ExistElement(&seqList, &person) != NO_FOUND ? printf("该元素存在\n") : printf("该元素不存在\n");
    ElemType * delElement;
    delElement = DeleteElement(&seqList, 0);
    printf("删除后:\n");
    PrintList(&seqList);
    printf("删除的元素是:\n");
    printf("[%d, %s]\n", delElement->id, delElement->name);
    //释放内存
    free(delElement);
    ExistElement(&seqList, &person) != NO_FOUND ? printf("该元素存在\n") : printf("该元素不存在\n");
}
运行结果
顺序表中的元素有:{ [1, 辉夜],[2, 羽衣],[3, 宇智波斑],[4, 羽村],[5, 漩涡鸣人],[6, 宇智波佐助] }
顺序表的长度是:6
该元素存在
删除后:
顺序表中的元素有:{ [2, 羽衣],[3, 宇智波斑],[4, 羽村],[5, 漩涡鸣人],[6, 宇智波佐助] }
删除的元素是:
[1, 辉夜]
该元素不存在
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值