数据结构与算法C语言版学习笔记(2)-线性表、顺序存储结构的线性表

news2025/2/23 3:00:35

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 数据结构部分的知识框架
  • 一、线性表的定义和特点
    • 1.定义
    • 2.特点
  • 二、线性表的实际案例引入
    • 1.案例一:多项式的加减乘除
    • 2.案例二:当多项式是稀疏多项式时:
      • ①稀疏多项式的定义:稀疏多项式(Sparse Polynomial)是指在多项式中,只有很少的系数是非零的情况下。具体地说,稀疏多项式是指多项式中的非零系数的数量远远小于总系数的数量。
    • 3.案例三:图书管理系统
  • 三、线性表的类型定义
    • 1.
  • 四、线性表的顺序表示和实现
    • 类C语言中的一些说明
      • 1.结构体嵌套
      • 2.静态数组与动态数组
    • 顺序表的示意图
      • ①线性表的插入元素
  • 五、顺序线性表的总结
    • 优点:
    • 缺点:


数据结构部分的知识框架

在这里插入图片描述
逻辑结构里面,线性表属于线性结构,是一个大类。区别与栈和队列、串等结构。
在这里插入图片描述
线性表主要从这8个部分进行学习。

一、线性表的定义和特点

1.定义

线性表是一种常见的数据结构,它是由一组有序的元素(节点)组成的数据序列。线性表中的元素之间存在一对一的关系,每个元素除了第一个元素外,都有唯一的前驱元素;每个元素除了最后一个元素外,都有唯一的后继元素。
在这里插入图片描述
举一个例子:
在这里插入图片描述
特点就是表里面的每个元素都具有相同的特征,要么都是字母,要么都是同一类的数据,而他们的关系就是一个接着一个连在一起。

2.特点

线性表的特点包括:
有序性:线性表中的元素按照一定的顺序排列,每个元素都有一个确定的位置。
唯一性:线性表中的元素都是唯一的,不存在相同的元素。
有限性:线性表中的元素个数是有限的,可以为空表(没有元素)或非空表(至少有一个元素)。
在这里插入图片描述

二、线性表的实际案例引入

1.案例一:多项式的加减乘除

在这里插入图片描述
一个多项式的每一项的系数可以用一个一维数组来表示,那么我们要进行多个多项式的加减乘运算,就可以只对相同指数(意味着他们数组的下标相同)的系数相加就可以,比如i[1]+j[1]就是第一项的系数和。

2.案例二:当多项式是稀疏多项式时:

①稀疏多项式的定义:稀疏多项式(Sparse Polynomial)是指在多项式中,只有很少的系数是非零的情况下。具体地说,稀疏多项式是指多项式中的非零系数的数量远远小于总系数的数量。

在这里插入图片描述
如果是几个稀疏多项式的加减,不可能让那些系数为0的2、3、4、5、6、7次项都存入线性表,不能去建立一个20000个元素的线性表,造成存储空间浪费,那么应该怎么做呢?
在这里插入图片描述
以这个为例,把多项式每一项的系数和指数都存储起来,形成线性表A和B,
在这里插入图片描述
如图,创建新数组C,遍历线性表A和B,比较是否有指数相同或不相同项,然后把各个指数项复制到数组C中即可。以一个具体的C语言代码为例:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int coefficient;  // 系数
    int exponent;  // 指数
} Term;

Term* addSparsePolynomials(Term* poly1, int size1, Term* poly2, int size2, int* resultSize) {
    int i = 0, j = 0, k = 0;
    int maxSize = size1 + size2;
    Term* result = (Term*)malloc(maxSize * sizeof(Term));  // 分配存储结果的数组

    while (i < size1 && j < size2) {
        if (poly1[i].exponent < poly2[j].exponent) {
            result[k++] = poly1[i++];  // 将poly1的项添加到结果中
        } else if (poly1[i].exponent > poly2[j].exponent) {
            result[k++] = poly2[j++];  // 将poly2的项添加到结果中
        } else {
            int coefficient = poly1[i].coefficient + poly2[j].coefficient;  // 相同指数的项系数相加
            if (coefficient != 0) {
                result[k].coefficient = coefficient;
                result[k].exponent = poly1[i].exponent;
                k++;
            }
            i++;
            j++;
        }
    }

    while (i < size1) {
        result[k++] = poly1[i++];  // 将poly1剩余的项添加到结果中
    }

    while (j < size2) {
        result[k++] = poly2[j++];  // 将poly2剩余的项添加到结果中
    }

    *resultSize = k;  // 更新结果的大小
    return result;
}

// 示例用法
int main() {
    Term poly1[] = {{3, 2}, {4, 1}, {2, 0}};  // 3x^2 + 4x + 2
    int size1 = sizeof(poly1) / sizeof(poly1[0]);
    Term poly2[] = {{2, 2}, {-1, 1}, {5, 0}};  // 2x^2 - x + 5
    int size2 = sizeof(poly2) / sizeof(poly2[0]);

    int resultSize;
    Term* result = addSparsePolynomials(poly1, size1, poly2, size2, &resultSize);

    printf("Result: ");
    for (int i = 0; i < resultSize; i++) {
        printf("%dx^%d ", result[i].coefficient, result[i].exponent);
        if (i != resultSize - 1) {
            printf("+ ");
        }
    }
    printf("\n");

    free(result);  // 释放分配的内存
    return 0;
}


这段代码实现了稀疏多项式的相加功能。稀疏多项式是指只有部分项存在的多项式,其中存在很多指数为0的项,其他项的指数按递增顺序排列。

代码中首先定义了一个结构体Term,用于表示多项式的每一项。每一项包含两个成员变量,coefficient表示系数,exponent表示指数。
在这里插入图片描述

接下来是addSparsePolynomials函数,该函数接受两个多项式的数组poly1和poly2,以及它们的大小size1和size2。函数的目标是将这两个多项式相加,并返回结果的数组。
在这里插入图片描述

函数中使用了三个变量i、j和k来分别追踪poly1、poly2和result数组的索引。maxSize变量用于存储结果数组的最大大小,即两个输入多项式的大小之和。通过malloc函数动态分配了一个大小为maxSize的result数组。
接下来的while循环通过比较指数的大小来相加多项式。如果poly1的当前项的指数小于poly2的当前项的指数,则将poly1的当前项添加到结果数组中,并递增i和k。如果poly1的当前项的指数大于poly2的当前项的指数,则将poly2的当前项添加到结果数组中,并递增j和k。如果两个当前项的指数相等,则将它们的系数相加,如果系数不为0,则将结果项的系数和指数设置为相加后的值,并将结果项添加到结果数组中。然后递增i、j和k。
在这里插入图片描述

接下来的两个while循环用于将剩余的多项式项添加到结果数组中,即如果poly1还有剩余项,则将它们全部添加到结果数组中,递增i和k;如果poly2还有剩余项,则将它们全部添加到结果数组中,递增j和k。
最后,将结果的大小k存储到resultSize指针指向的变量中,并返回结果数组。

在main函数中,我们定义了两个多项式poly1和poly2,并计算它们的大小。然后调用addSparsePolynomials函数来求解它们的相加结果,并将结果存储在result数组中。最后,使用循环打印出结果数组中的项,并释放动态分配的内存。
在这里插入图片描述

3.案例三:图书管理系统

在这里插入图片描述
因为需要进行较多的查找、插入、删除、修改操作,使用链式结构的话会更加方便一些。链式结构只需要对节点进行修改,不像数组一样每次都要将插入节点之后所有的元素都整体后移或者前移,浪费时间,并且会频繁分配与释放内存。

三、线性表的类型定义

1.

在这里插入图片描述
这其中有很多伪代码组成的基本操作,这里不一一介绍了。

四、线性表的顺序表示和实现

在这里插入图片描述
在这里插入图片描述
比如一个数组就是线性表,定义一个整形数组,一个元素占32位,即4个字节,已知第3个元素的位置的话,那么下一个元素位置就是指针指向+4个字节的位置。所以有个好处:查找表中的某一个元素非常方便。
在这里插入图片描述
这里有一个点:顺序线性表长度是可以变化的,但是初始建立顺序线性表时表的长度只能定义为一个准确的数值,而不是一个动态变化的变量。可以用这个模板作为线性表的构建:在这里插入图片描述
在这里插入图片描述
指针*elem指向结构体的起始地址。同时有一个嵌套结构体的结构体。
举一个实际的例子:
在这里插入图片描述
定义了一个线性表Book,成员包括ISBN码、名字和价格。又创建了一个结构体指针elem,length是线性表中的元素个数。

类C语言中的一些说明

1.结构体嵌套

在这里插入图片描述
这个结构体中的ElemType是什么类型的?
答:它是一个抽象类型,ElemType就是一个结构体的名字,
typedef struct {
int coefficient;
int exponent;
char name[20];
float price;
} ElemType;
ElemType内含多个数据类型,所以它是抽象的,可以定义成int型,也可以定义为char型。

2.静态数组与动态数组

在这里插入图片描述
静态数组中元素的大小是确定的,Maxsize是一个宏定义后的常量,但是动态数组的话,data可以通过函数如malloc()或new来进行,需要手动释放内存以避免内存泄漏。例如,int* arr = malloc(sizeof(int) * 10);。这样的话,sizeof()函数每次都可以计算变化后当前数组的大小,malloc()函数再开辟一块空间给数组。这几个函数有什么作用:
在这里插入图片描述

顺序表的示意图

在这里插入图片描述
有了顺序表sqlist,还要定义一个变量L,L是顺序表类型。

如何操作线性表里面的元素呢?这一块的内容我下一节单独列出,写代码。
在这里插入图片描述

①线性表的插入元素

在这里插入图片描述
思考如何插入一个元素到线性表中:
在这里插入图片描述

五、顺序线性表的总结

在这里插入图片描述
线性表的顺序存储结构是使用数组来存储线性表的元素,具有以下优点和缺点:

优点:

随机访问:由于元素在数组中是连续存储的,可以通过下标直接访问任意位置的元素,具有快速的随机访问速度。
空间效率高:顺序存储结构只需要额外的一个数组来存储元素,不需要额外的指针等辅助空间,因此空间利用率高。
索引操作简单:通过下标索引即可访问和修改元素,操作简单明了。

缺点:

插入和删除操作耗时:在顺序存储结构中,插入和删除操作需要将插入或删除位置后面的元素依次后移或前移,需要移动大量元素,因此耗时较长。
动态扩容困难:顺序存储结构的数组大小是固定的,如果线性表的元素个数超过了数组的容量,需要重新分配更大的数组并将元素复制到新数组中,比较麻烦。
内存浪费:如果线性表的元素个数远小于数组的容量,会造成内存的浪费,因为数组的大小是固定的。
综上所述,顺序存储结构适合于需要频繁随机访问元素、对空间要求较高、不需要频繁插入和删除操作的场景。如果需要频繁的插入和删除操作,或者线性表的大小不确定,动态变化,就可以考虑使用其他存储结构,如链式存储结构(链表)来实现线性表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1178283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI 女友突然下线,大叔集体「崩溃」;谷歌聊天机器人称谷歌滥用垄断力量丨 RTE 开发者日报 Vol.78

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

微服务项目,请求从发出到后端处理器的历程

点击登录按钮,发出 http://localhost:8803/service_6001/admin/login/in请求,这是一个由nginx配置的前端项目 查看配置文件,该条请求会被映射形成对http://localhost:51603/admin/login/in的post请求 upstream heima-admin-gateway {server localhost:51603; } server {liste…

笔记50:正则表达式入门宝典

引自&#xff1a;正则表达式是什么? - 知乎 中“龙吟九野”所写的一个回答&#xff0c;个人感觉看完之后如同醍醐灌顶&#xff0c;查了很多资料都没有这篇文章写的基础和通透&#xff0c;感觉是正则表达式扫盲好文&#xff0c;所以搬运一下&#xff0c;侵权删&#xff0c;感谢…

吃透BGP,永远绕不开这些基础概述,看完再也不怕BGP了!

你们好&#xff0c;我的网工朋友。 总有人在私信里抱怨&#xff0c;BGP实在是太难了&#xff01; 一是这玩意儿本来就很复杂&#xff0c;需要处理大量的路由信息和复杂的算法&#xff1b;再一个是需要你有一定的实战经验才能深入理解运作。 虽然BGP确实有一定难度&#xff0c…

简简单单入门Makefile

笔记来源&#xff1a;于仕琪教授&#xff1a;Makefile 20分钟入门&#xff0c;简简单单&#xff0c;展示如何使用Makefile管理和编译C代码 操作环境 MacosVscode 前提准备 新建文件夹 mkdir learn_makefile新建三个cpp文件和一个头文件 // mian.cpp #include <iostrea…

fio数据整理之二

fio数据简单抓取 上文我们完成了一些fio output数据的简单抓取&#xff0c;本文将针对抓取的数据做进一步的处理&#xff0c;输出到表格之中&#xff0c;方便我们查看&#xff0c;统计结果。 本文先使用最简单的方法创建csv档案 我们现有个基本认知&#xff0c;在csv档案中&am…

通过you-get命令行工具下载B站等常见网站高清视频

参考&#xff1a; you-get&#xff1a;https://github.com/soimort/you-get EditThisCookie 源码&#xff1a;https://github.com/ETCExtensions/Edit-This-Cookie EditThisCookie 官网&#xff1a;https://www.editthiscookie.com/ you-get 是一个非常好用的命令行版视频下载工…

[wp]NewStarCTF 2023 WEEK5|WEB

前言:比赛是结束了&#xff0c;但我的学习还未结束&#xff0c;看看自己能复习几道题吧&#xff0c;第四周实在太难 Final 考点&#xff1a; ThinkPHP 5.0.23 RCE一句话木马上传SUID提权&#xff08;find&#xff09; 解题: 首先页面就给了ThinkPHP V5&#xff0c; 那无非考…

java制作游戏,如何使用libgdx,入门级别教学

第一步&#xff0c;进入libgdx的官网。点击get started 进入这个页面&#xff0c;点击setup a project 进入这个页面直接点击&#xff0c;Generate a project. 点击下载&#xff0c;下载创建工具 它会让你下载一个jar包&#xff0c;有java环境的人可以双击直接打开。 把android…

Linux学习之vim跳转到特定行数

参考的博客&#xff1a;《Vim跳到最后一行的方法》 《oeasy教您玩转vim - 14 - # 行头行尾》 《Linux&#xff1a;vim 中跳到首行和最后一行》 想要跳到特定行的话&#xff0c;可以在命令模式和正常模式进行跳转。要是对于vim的四种模式不太熟的话&#xff0c;可以到博客《Linu…

Arrays.asList() 和 List.of() 的列表之争

1. 概述 有时在Java中&#xff0c;为了方便&#xff0c;我们需要创建一个小列表或将数组转换为列表。Java 为此提供了一些辅助方法。 在本文中&#xff0c;我们将比较初始化小型临时数组的两种主要方法&#xff1a;List.of()和 Array.asList()。 2. Arrays.asList() Java 自…

跨境电商商城源码,助力商家全球布局(多语言切换\多货币转换\多商户入驻)

今天&#xff0c;我们要给大家介绍一款强大且多元化的跨境电商解决方案——WoShop跨境电商源码!这款源码拥有许多令人惊叹的功能&#xff0c;其中最引人注目的就是支持多语言切换、多货币转换以及多商户入驻! 设想一下&#xff0c;你是一个跨境电商的卖家&#xff0c;你的业务遍…

Cannot read properties of undefined (reading ‘prototype‘)

用vue注册的用import ElementUI from "element-ui"是不行的要用 import ElementUI from “element-plus”

【JAVA学习笔记】63 -坦克大战1.3-敌方发射子弹,击中坦克消失并爆炸,敌人坦克随机移动,规定范围限制移动

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter18/src/com/yinhai/tankgame1_3 〇、要求 增加功能 1.让敌人的坦克也能够发射子弹(可以有多颗子弹) 2.当我方坦克击中敌人坦克时&#xff0c;敌人的坦克就消失,如果能做出爆炸效果更好. …

Thread类的基本操作(JAVA多线程)

线程是操作系统中的概念&#xff0c;操作系统内核实现了线程这样的机制&#xff0c;并提供了一些API供外部使用。 JAVA中 Thread类 将系统提供的API又近一步进行了抽象和封装&#xff0c;所以如果想要使用多线程就离不开 Thread 这个类。 线程的创建(Thread类) 在JAVA中 创建…

SPSS多元方差分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

大容量中间继电器 RXMH2 RK223 067 DC110V JOSEF约瑟

系列型号 RXMH2 RK 223 067大容量中间继电器&#xff1b; RXMH2 RK 223 068大容量中间继电器&#xff1b; RXMH2 RK 223 069大容量中间继电器&#xff1b; RXMH2 RK 223 070大容量中间继电器&#xff1b; 一、用途 RXMH2系列大容量中间继电器用于工业自动化控制及电力系统…

Git介绍及使用

目录 一、Git 的基本概念 1. 仓库&#xff08;Repository&#xff09;: 仓库是存储代码的地方。可以通过 命令将本地文件夹初始化为 Git 仓库&#xff0c;并使用 命令从远程仓库克隆到本地 2. 分支&#xff08;Branch&#xff09;: 分支是指从主分支上创建出来的一个分支&…

Python画一个爱心

Python画一个爱心 一、效果图二、Python代码 一、效果图 二、Python代码 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 480 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CA…

DCU集群搭建虚拟环境方法简介

1.conda安装方法&#xff1a; wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh #下载miniconda安装包chmod 750 Miniconda3-latest-Linux-x86_64.sh #添加执行权限bash ./Miniconda3-latest-Linux-x86_64.sh #安装下载的minnconda32.集群安装…