首页 > 其他分享 >C语言实现顺序存储线性表

C语言实现顺序存储线性表

时间:2025-01-20 15:14:02浏览次数:1  
标签:return 线性表 int 元素 C语言 length Book 顺序存储


//
// Created by steve xiaohu zhao on 2025/1/20.
//

/**
 *
 * 线性表的顺序存储结构实现
 * 特点:逻辑上相邻的元素,物理上也相邻
 *
 */


#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100     // 定义线性表的最大长度

// 1. 定义图书结构体 Book
typedef struct {
    char no[20]; // 图书 ISBN 号
    char name[50]; // 图书名称
    float price; // 图书价格
} Book; // 定义图书结构体


// 2. 定义线性表结构体 SqList
typedef struct {
    Book *elements; // 存储空间基址
    int length; // 当前长度(图书表中当前图书个数)
} SqList; // 定义线性表结构体


// 3. 初始化线性表, 顺序表的初始化操作就是构造一个空的顺序表
int initList(SqList *L) {
    L->elements = (Book *) malloc(MAXSIZE * sizeof(Book)); // 为顺序表分配存储空间
    if (!L->elements) {
        return -1; // 存储分配失败
    }
    L->length = 0; // 空表长度为0
    return 0; // 初始化成功
}

// 4. 销毁线性表
void destroyList(SqList *L) {
    free(L->elements); // 释放存储空间
    L->length = 0; // 线性表长度清零
}

// 5. 清空线性表
void clearList(SqList *L) {
    L->length = 0; // 线性表长度清零
}

// 6. 判断线性表是否为空
int listEmpty(SqList L) {
    return L.length == 0; // 线性表为空返回1,否则返回0
}

// 7. 获取线性表的长度
int listLength(SqList L) {
    return L.length; // 返回线性表的长度
}

// 8. 获取线性表中第 i 个元素,注意:这里的 i 是第几个元素,不是数组下表
int getElem(SqList L, int i, Book *e) {
    if (i < 1 || i > L.length) {
        return -1; // i 值不合法
    }
    *e = L.elements[i - 1]; // 将第 i 个元素的值赋给 e
    return 0; // 获取成功
}

// 9. 按值查找,查找线性表中是否存在元素 e
// 顺序表查找的时间复杂度为 O(n),比较的次数平均为 (n+1)/2
int locateElem(SqList L, Book e) {
    for (int i = 0; i < L.length; i++) {
        // 如果两个元素的 ISBN 号相同,则认为这两个元素相等
        // 如果两个元素相等,则返回元素 e 在线性表中的位置
        // 此处的 i 表示元素的索引,i + 1 表示元素在线性表中的位置
        if (L.elements[i].no == e.no) {
            return i + 1; // 返回元素 e 在线性表中的位置
        }
    }
    // 因为位置是从 1 开始的,所以返回 0 表示不存在元素 e
    return 0; // 线性表中不存在元素 e
}

// 10. 插入元素, 在线性表的第 i 个位置插入元素 e, 注意:这里的 i 是第几个元素,不是数组下表
// 在第 i 个元素位置插入元素 e,表示要在第 i - 1 个索引处插入元素 e
// 顺序表插入的平均时间复杂度为 O(n), 移动元素的次数平均为 n/2
int listInsert(SqList *L, int i, Book e) {
    if (i < 1 || i > L->length + 1) {
        return -1; // i 值不合法
    }
    // 如果线性表已满,则无法插入元素(此处没有处理线性表扩充的问题)
    if (L->length >= MAXSIZE) {
        return -1; // 线性表已满
    }

    // 从最后一个元素索引开始,直到第 i - 1 个索引处,将元素依次后移
    for (int j = L->length - 1; j >= i - 1; j--) {
        L->elements[j + 1] = L->elements[j]; // 将第 i 个元素及之后的元素后移
    }
    L->elements[i - 1] = e; // 在位置 i 插入元素 e
    L->length++; // 线性表长度加 1
    return 0; // 插入成功
}

// 11. 删除元素, 删除线性表的第 i 个元素,并将删除的元素赋值给 e
// 顺序表删除的平均时间复杂度为 O(n), 移动元素的次数平均为 (n-1)/2
int listDelete(SqList *L, int i, Book *e) {
    if (i < 1 || i > L->length) {
        return -1; // i 值不合法
    }
    *e = L->elements[i - 1]; // 将删除的元素赋值给 e
    // 从第 i 个元素索引开始,直到最后一个元素索引处,将元素依次前移
    // 注意:这里的 i 是第几个元素,不是数组下标
    for (int j = i; j < L->length; j++) {
        L->elements[j - 1] = L->elements[j]; // 将第 i 个元素之后的元素前移
    }
    L->length--; // 线性表长度减 1
    return 0; // 删除成功
}

// 12. 打印线性表中的所有元素
void listPrint(SqList L) {
    for (int i = 0; i < L.length; i++) {
        printf("第 %d 个元素的 ISBN 号:%s, 名称:%s, 价格:%.2f\n", i + 1, L.elements[i].no, L.elements[i].name,
               L.elements[i].price);
    }
}

// 13. 测试线性表的顺序存储结构

int testSqList() {
    SqList L; // 定义一个线性表
    Book e; // 定义一个图书元素
    // 初始化线性表
    if (initList(&L) == -1) {
        printf("初始化线性表失败!\n");
        return -1;
    }

    // 判断线性表是否为空
    printf("线性表是否为空:%d\n", listEmpty(L));

    // 插入元素
    Book book1 = {"1001", "C 语言程序设计", 35.5};
    listInsert(&L, 1, book1);
    Book book2 = {"1002", "数据结构", 45.5};
    listInsert(&L, 2, book2);
    Book book3 = {"1003", "计算机网络", 55.5};
    listInsert(&L, 3, book3);
    Book book4 = {"1004", "操作系统", 65.5};
    listInsert(&L, 4, book4);
    Book book5 = {"1005", "数据库系统", 75.5};
    listInsert(&L, 5, book5);

    // 插入到第 2 个位置
    Book book6 = {"1006", "计算机组成原理", 85.5};
    listInsert(&L, 2, book6);

    // 打印线性表中的所有元素
    listPrint(L);


    // 获取线性表的长度
    printf("线性表的长度:%d\n", listLength(L));

    // 获取线性表中第 3 个元素
    getElem(L, 3, &e);
    printf("第 3 个元素的 ISBN 号:%s, 名称:%s, 价格:%.2f\n", e.no, e.name, e.price);

    // 按值查找元素
    Book model = {"1003", "计算机网络", 55.5};
    printf("元素 %s 在线性表中的位置:%d\n", model.no, locateElem(L, model));

    // 删除元素
    listDelete(&L, 3, &e);
    printf("删除的元素的 ISBN 号:%s, 名称:%s, 价格:%.2f\n", e.no, e.name, e.price);

    // 打印线性表中的所有元素
    listPrint(L);

    // 清空线性表
    clearList(&L);

    // 获取线性表的长度
    printf("线性表的长度:%d\n", listLength(L));

    // 销毁线性表
    destroyList(&L);

    // 返回 0 表示测试成功
    return 0;
}


int main(int argc, const char *argv[]) {
    // 测试线性表的顺序存储结构
    testSqList();

    return 0;
}



标签:return,线性表,int,元素,C语言,length,Book,顺序存储
From: https://www.cnblogs.com/zxhoo/p/18681402

相关文章

  • 栈的顺序存储代码
    #include<stdio.h>#include<stdlib.h>#pragmawarning(disable:4996)#defineelemTypeint#definemaxSize50typedefstructseqStack{   elemTypearr[maxSize];   inttop;}seqStack;voidinitStack(seqStack*stack){   for(inti=0;......
  • 线性表
    线性表1.基本概念线性表是包含若干数据元素的一个线性序列,记为:\(L=(a_0,...a_{i-1},a_i,a_{i+1}...a_{n-1})\)其中,L为表名,\(a_i(0\leqi\leqn-1)\)为数据元素;n为表长,n>0时,线性表为非空表,否则为空表。二元组形式表述:​ $$L=(D,R)$$即线性表L包含数据元素集......
  • 指针应用-查找数组元素(PTA)C语言
    编写一个名为findX的函数,该函数的参数p指向一个int数组,数组的容量n由参数2指定。在该数组中,查找数据x所在的位置。如果数据x有出现多次,则返回其最后一次出现的位置对应的下标。如果没有找到,则固定返回-2。intfindX(int*p,intn,intx);函数接口定义:intfindX(int*p,intn......
  • C语言:分支语句详解
           所谓分支,就是在不同情况下输出不同结果。下面我们来学习分支语句:1.if语句1.1if    if语句的书写方法如下:if(表达式)语句       如果表达式值为真,那么我们就执行语句,若表达式值不为真(为假),就不执行。在C语言中,我们说非0为真,0为假。我......
  • C语言的应用|猜数字游戏
    目录1.引言2.rand(包含在中)3.srand(包含在中)4.time(包含在中)5.游戏代码showtime1.引言  哈喽,大家好,好久不见。今天小邓儿,将带咱们用C语言,来写一个小游戏——猜数字。不过,编写游戏之前。先给大家拓展一些相关知识点(●'◡'●)2.rand(包含在<stdlib.h>中)1.1 ......
  • 初识C语言
    1.什么是c语音C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个......
  • 比特c语言-分支与循环
      #分支与循环if语句目录if语句ifeg:输入一个整数,判断是否为奇数elseeg:输入一个整数,判断是否为奇数,如果是奇数打印是奇数,否则打印偶数嵌套ifeg:输入一个人的年龄关系操作符条件操作符eg:使用条件操作符表示代码逻辑eg:使用条件表达式找两个数中较大值逻辑操作符:&&,||,!eg:闰年的......
  • C语言文件操作—看完还不会欢迎留言!不收藏就找不到了a!
    本章作为科普篇,大家在工作时可能用的很少,但不看白不看嘛!看完一定加深编程语言与计算机之间的理解! 我们看本章的几个重点:1:为什么要使用文件?2:什么是文件3:文件的打开与关闭4:文件的使用方式5:文件的顺序读写6:文件的随机读写(C语言阶段只需要掌握以上即可!)为什么要使用文件......
  • C语言-预处理命令
    1、预处理命令是以# 开头的指令        用于在编译前对源代码进行一些处理2、与#号相关的代码    1、#include                用于在源代码中引入其他文件。可以引入标准库的头文件,也可以引入自定义的头              ......
  • C语言 - 函数
    1、作用    1、可以让程序模块化    2、可以减少重复代码    3、提高程序的可读性、可维护性和重用性2、函数的三个部分    1、函数的定义        函数类型函数名(数据类型1形参1,数据类型2形参2,...)     ......