当前位置: 首页 > news >正文

佛科院计算机软件技术基础——线性表

一、基础知识了解:

  1. 结构体的理解:

我们知道整型是由1位符号位和15位数值位组成,而就可以把结构体理解为我们定义的数据类型,如:

typedef struct
{int data[2];        //存储顺序表中的元素int len;                        //顺序表的表长
}SeqList;                             //顺序表类型

在这个结构体中我们定义前2*16位存放顺序表中的数据,最后1*16位存放表长

对于:

SeqList List;

这个就是类似于整型的一个结构体类型的变量,我们可以通过(List.len/List.data[i])调用结构体变量中的元素。

对于:

SeqList *L;//等同于int *L;,只不过可指向的数据类型不同

不过跟int *L;相同的,定义只是一个空指针,需要通过申请一段内存空间才能使用:

L=(SeqList*)malloc(sizeof(SeqList));
  1. 结构体变量的地址:

结构体变量的地址为首个成员的地址

  1. 指针的理解:

指针是一种通过指向地址来操纵数据的方式

如:

typedef struct
{//MAXSIZE是根据实际问题所定义的一个足够大的整数//datatype为顺序表中元素的类型,在具体实现中可为int、float、char类型或其他结构类型datatype data[MAXSIZE];        //存储顺序表中的元素int len;                        //顺序表的表长
}SeqList;                             //顺序表类型//构造一个空表
SeqList *Init_SeqList()
{SeqList *L;//建立一个SeqList类型的空指针L=(SeqList*)malloc(sizeof(SeqList));//申请空间,并让L指向该空间的地址L->len=0; //顺序表的表长为0return L;
}
  1. 对SeqList **L的理解:

对于:

typedef struct node
{datatype data;            //data为结点的数据信息struct node *next;      //与SeqList *L;类似,存放了另一个LNode结构体变量的首地址
}LNode;                                  

我们可以重点看struct node *next; ,如果我们要操作next地址对应结构体的数据data,我们就要用到SeqList **L

如:

一、顺序表

  1. 顺序表定义:

typedef struct
{//datatype为表中元素类型(int,float等)//元素存放在data数组中//MAXSIZE是根据实际问题所定义的一个足够大的整数datatype data[MAXSISE];int len;//表长
}SeqList;
  1. 指向顺序表的指针变量

SeqList list,*L;
//list是结构体变量,它内部含有一个可存储顺序表的data数组
//L是指向List这类结构体变量的指针变量

其中:

(1)List.data[i]或L->data[i]均表示顺序表中第i个元素的值

(2)List.len或L->len均表示顺序表的表长

(3)“L=(SeqList*)malloc(sizeof(SeqList));”表示生成一个顺序表存储空间

  1. 顺序表的初始化

typdefine struct 
{datatype data[MAXSIZE];int len;
}Seqlist;
Seqlist *seqlist_Init()
{Seqlist *l;l = (Seqlist*)malloc(sizeof(Seqlist));l->len = 0;return l;
}
  1. 建立顺序表:(没搞懂)

(1)头部插入

先读取需要输入数据个数,再进行读取外部数据操作,最后将数据按顺序存放到顺序表中的数组

void CreatList(SeqList **L)
{int i, n;printf("Input length of List: ");scanf("%d", &n);printf("Input elements of List: \n");for(i=1;i<=n;i++)scanf("%d", &(*L)->data[i]);(*L)->len=n;
}

(2)尾部插入

LNode *CreateLinkList()
{LNode *head, *p, *q; char x;head=(LNode*)malloc(sizeof(LNode));       //生成头结点head->next=NULL;p=head; q=p;                                    //指针q始终指向链尾结点printf("Input any char string: \n");scanf("%c", &x);while(x!='\n')                                  //生成链表的其他结点{p=(LNode*)malloc(sizeof(LNode));p->data=x;p->next=NULL;q->next=p;                                    //在链尾插入q=p;scanf("%c", &x);}return head;                                   //返回单链表表头指针
}
  1. 插入运算:

先判断表是否满了和插入位置是否合理,再将i到len个从后面到前面逐个向后移,最后再插入到第i个位置

void Insert_SeqList(SeqList *L, int i, datatype x)
{int j;if(L->len==MAXSIZE-1)                   //表满printf("The List is full!\n");elseif(i<1|| i>L->len+1)                //插入位置非法printf("The position is invalid !\n");else{for(j=L->len;j>=i;j--)          //将an~ai顺序后移一个元素位置L->data[j+1]=L->data[j];L->data[i]=x;                   //插入x到第i个位置L->len++;                          //表长增1}
}}
  1. 删除运算:

void Del_LinkList(LNode *head , int i)
{                     //删除单链表head上的第i个数据结点LNode *p, *q;p=Get_LinkList(head, i-1);               //查找第i-1个结点if(p==NULL)printf("第i-1个结点不存在!\n "); //待删结点的前一个结点不存在,无待删结点elseif(p->next==NULL)printf("第i个结点不存在!\n");        //待删结点不存在else{q=p->next;                //q指向第i个结点p->next=q->next;            //从链表中删除第i个结点free(q);                //系统回收第i个结点的存储空间}
}
  1. 查找:

给值查找存储位置:以该一位元素是否为x和该位是否在在顺序表中为判断条件,最后如果跳出时的元素为x则返回i,不是则返回0

int Location_SeqList(SeqList *L, datatype x)
{int i=1;                                  //从第一个元素开始查找while(i<L->len&&L->data[i]!=x)//顺序表未查完且当前元素不是要找的元素i++;if(L->data[i]==x)return i;                                //找到则返回其位置值elsereturn 0;                                              //未找到则返回0值
}

二、单链表

  1. 单链表结点定义:

只需要定义一个存放数据和后一个节点地址的结构体就行


typedef struct node
{datatype data;            //data为结点的数据信息struct node *next;      //next为指向后继结点的指针
}LNode;                                  //单链表结点类型
  1. 建立单链表:

首先建立一个任意的头节点,读取外部输入数据,

void CreateLinkList(LNode **head)
{                       //将主调函数中指向待生成单链表的指针地址(如&p)传给**headchar x;LNode *p;*head=(LNode *)malloc(sizeof(LNode)); //在主调函数空间生成链表头结点(*head)->next=NULL;        //*head为链表头指针printf("Input any char string: \n");scanf("%c", &x);      //结点的数据域为char型,读入结点数据while(x!='\n')             //生成链表的其他结点{p=(LNode *)malloc(sizeof(LNode));     //申请一个结点空间p->data=x;p->next=(*head)->next;       //将头结点的next值赋给新结点*p的next(*head)->next=p;    //头结点的next指针指向新结点*p实现在表头插入scanf("%c", &x);            //继续生成下一个新结点}

(1)为什么使用LNode **head?(未解决)

由于我们要与主函数联系起来,必须确定头节点的

  1. 查找:

(1)按序号:

根据指针域一直寻址到第i个结点,以循环次数与最后一个节点为结束标志

LNode *Get_LinkList(LNode *head, int i)
{                                 //在单链表head中查找第i个结点LNode *p=head;              //由第一个结点开始查找int j=0;while(p!=NULL&&j<i)         //当未查到链尾且j小于i时继续查找{p=p->next;j++;}return p;           //找到则返回指向i结点的指针值,找不到则p返回空值
}

(2)按值查找:

根据指针域一直寻址,以找到目标值和最后一个数为结束标志

LNode *Locate_LinkList(LNode *head, char x)
{                                //在单链表中查找结点值为x的结点LNode *p=head->next;     //由第一个数据结点开始查找while(p!=NULL&&p->data!=x) //当未查到链尾且当前结点不等于x时继续查找p=p->next;return p; //找到则返回指向值为x的结点的指针值,找不到则p返回空值
}
  1. 求表长:

从第一个结点寻址到最后一个结点,并做计数

int Length_LinkList(LNode *head)
{LNode *p=head;                //p指向单链表头结点int i=0;                         //i为结点计数器while(p->next!=NULL){p=p->next;i++;}return i;                       //返回表长值i
}
  1. 插入:

利用查找函数获得第i-1个结点的地址,如果该结点地址为空(即最后一个结点),说明插入操作非法;如果不为空,创建一个新节点数据域存放插入数据,指针域域存放下一个结点的地址,上一个结点的指针域放新节点的地址

void Insert_LinkList(LNode *head, int i, char x)
{                                               //在单链表head的第i个位置上插入值为x的元素LNode *p, *q;p=Get_LinkList(head, i-1);            //查找第i-1个结点*/if(p==NULL) printf("Error ! \n");                 //第i-1个位置不存在而无法插入else{q=(LNode *)malloc(sizeof(LNode));    //申请结点空间q->data=x;q->next=p->next;                      //完成插入操作①p->next=q;                             //完成插入操作②}
}
  1. 删除:

首先像插入操作一样判断删除操作是否非法,如果合法,则让第i-1个结点的地址域直接存放第i+1个结点的地址,同时把第i个结点的空间释放

算法如下:
void Del_LinkList(LNode *head , int i)
{                     //删除单链表head上的第i个数据结点LNode *p, *q;p=Get_LinkList(head, i-1);               //查找第i-1个结点if(p==NULL)printf("第i-1个结点不存在!\n "); //待删结点的前一个结点不存在,无待删结点elseif(p->next==NULL)printf("第i个结点不存在!\n");        //待删结点不存在else{q=p->next;                //q指向第i个结点p->next=q->next;            //从链表中删除第i个结点free(q);                //系统回收第i个结点的存储空间}
}

三、循环链表

  1. 查找循环链表中某个数:

与单链表类似,只不过最后的一个查找的地址不是NULL而是头节点

LNode *Locate_CycLink(LNode *head, datatype x)
{LNode *p=head->next;       //由第一个数据结点开始查while(p!=head&&p->data!=x)//未查完循环链表且当前结点不等于x时继续查找p=p->next;if(p!=head)                       //head   代表结束点return p;              //找到值等于x的结点*p,返回其指针值pelsereturn NULL; //当p又查到头结点时则无等于x值的结点,故返回NULL值
}

四、单链表应用

例1:

通过两个指针将

void Convert(LNode *H)
{LNode *p, *q;p=H->next;               //p指向剩余结点链表的第一个数据结点H->next=NULL;               //新链表H初始为空while(p!=NULL){q=p;                   //从剩余结点链表中取出第一个结点p=p->next;             //p继续指向剩余结点链表新的第一个数据结点q->next=H->next;     //将取出的结点*q插入新链表H的链首H->next=q;}
}

例2:

首先把A的头节点赋给C,释放B的头节点,再将A、B中较小的用头插法赋给C,再该链表推进到下一个结点,循环该操作直到A,B中任意一方到最后一个结点,最后将剩余元素用头插法赋给C

 void Merge(LNode *A, LNode *B, LNode **C)
{                           //将增序链表A、B合并成降序链表*CLNode *p, *q, *s;p=A->next;              //p始终指向链表A的第一个未比较的数据结点q=B->next;               //q始终指向链表B的第一个未比较的数据结点*C=A;                     //生成链表的*C的头结点(*C)->next=NULL;free(B);                 //回收链表B的头结点空间while(p!=NULL&&q!=NULL){   //将A、B两链表中当前比较结点中值小者赋给*sif(p->data<q->data){s=p;   p=p->next;}else{s=q; q=q->next;}s->next=(*C)->next; //用头插法将结点*s插到链表*C的头结点之后(*C)->next=s;}if(p==NULL)    //如果指向链表A的指针*p为空,则使*p指向链表Bp=q;while(p!=NULL){//将*p所指链表中的剩余结点依次摘下插入链表*C的链首s=p;p=p->next;s->next=(*C)->next;   (*C)->next=s;}

例3:

首先建立一个单链表,再将最后一个地址域赋上头节点地址形成循环列表,

void Josephus(int n, int m, int k)
{LNode *p, *q;int i;p=(LNode*)malloc(sizeof(LNode));q=p;for(i=1;i<n;i++)     //从编号k开始建立一个单链表{q->data=k;k=k%n+1;q->next=(LNode*)malloc(sizeof(LNode));q=q->next;}q->data=k; q->next=p;              //链接成循环单链表,此时p指向编号为k的结点while(p->next!=p)       //当循环单链表中的结点个数不为1时{for(i=1;i<m;i++){q=p;  p=p->next;}                          //p指向报数为m的结点,q指向报数为m-1的结点q->next=p->next;              //删除报数为m的结点printf("%4d", p->data);       //输出出圈人的编号free(p);                      //释放被删结点的空间p=q->next;                    //p指向新的开始报数结点}printf("%4d", p->data);         //输出最后出圈人的编号
}

相关文章:

佛科院计算机软件技术基础——线性表

一、基础知识了解&#xff1a;结构体的理解&#xff1a;我们知道整型是由1位符号位和15位数值位组成&#xff0c;而就可以把结构体理解为我们定义的数据类型&#xff0c;如&#xff1a;typedef struct {int data[2]; //存储顺序表中的元素int len; …...

linux下终端操作mysql数据库

目录 一&#xff0e;检查mysql是否安装 1. 查看文件安装路径 2. 查询运行文件所在路径(文件夹地址) 二&#xff0e;登录mysql 三&#xff0e;列出mysql全部用户 四&#xff0e;常用指令 &#xff11;&#xff0e;查看全部数据库 &#xff12;&#xff0e;选择数据库 …...

MySQL参数优化之thread_cache_size

1.thread_cache_size简介 每建立一个连接&#xff0c;都需要一个线程来与之匹配&#xff0c;此参数用来缓存空闲的线程&#xff0c;以至不被销毁&#xff0c;如果线程缓存中有空闲线程&#xff0c;这时候如果建立新连接&#xff0c;MYSQL就会很快的响应连接请求。 show statu…...

gRPC服务健康检查(二):gRPC健康检查协议详解

gRPC健康检查协议健康检查用于检测服务端能否正常处理rpc请求&#xff0c;客户端对服务端的健康检查可以点对点进行&#xff0c;也可以通过某些控制系统&#xff08;如负载平衡&#xff09;进行。客户端可以根据服务端返回的状态执行对应的策略。因为GRPC服务可以用于简单的客户…...

Android系统10 RK3399 init进程启动(四十七) Android init 进程整体代码逻辑简述

配套系列教学视频链接&#xff1a;安卓系列教程之ROM系统开发-百问100ask说明系统&#xff1a;Android10.0设备&#xff1a; FireFly RK3399 &#xff08;ROC-RK3399-PC-PLUS&#xff09;前言本文简单描述一下android init祖先进程启动的基本执行流程&#xff0c;让大家有一个整…...

CSDN 编程竞赛三十二期题解

竞赛总览 CSDN 编程竞赛三十二期&#xff1a;比赛详情 (csdn.net) 竞赛题解 题目1、传奇霸业 传奇霸业&#xff0c;是兄弟就来干。小春&#xff08;HP为a&#xff09;遇到了一只黄金哥布林&#xff08;HP为x&#xff09;。小春每次能对哥布林造成b点伤害&#xff0c;哥布林…...

Kubernetes 中的 Pod Hook

Pod Hook 我们知道Pod是Kubernetes集群中的最小单元&#xff0c;而 Pod 是有容器组组成的&#xff0c;所以在讨论 Pod 的生命周期的时候我们可以先来讨论下容器的生命周期。 实际上 Kubernetes 为我们的容器提供了生命周期钩子的&#xff0c;就是我们说的Pod Hook&#xff0c…...

Linux操作系统安装MySQL(rpm安装)

Linux操作系统安装MySQL&#xff08;rpm安装&#xff09;1 背景2 环境说明3 准备工作3.1 端口查看3.2 检查安装3.3 创建MySQL用户和组4 MySQL安装4.1 下载MySQL4.2 解压安装包4.3 安装MySQL4.4 初始化MySQL4.5 启动MySQL4.6 设置MySQL初始密码4.6.1 查看数据库初始密码4.6.2 更…...

MySQL高级第二讲

目录 二、MySQL高级02 2.1 触发器 2.1.1 触发器介绍 2.1.2 创建触发器 2.2 MySQL的体系结构 2.3 存储引擎 2.3.1 存储引擎概述 2.3.2 各种存储引擎特性 2.3.3 InnoDB 2.3.4 MyISAM 2.3.5 MEMORY 2.3.6 MERGE 2.3.7 存储引擎的选择 2.4 优化sql 2.4.1 查看sql执行…...

凸优化专题1

多变量函数的求导与求梯度/矩阵求导 1. 导数 定义: 设f:Rn→Rm,且x∈intdomf,则f在点x的导数(或称Jacobian)记为矩阵Df(x)∈Rmnf:\R^n \rightarrow \R^m, 且x\in \mathbf{int}\ \mathbf{dom} f, 则f 在点x的导\\数(或称Jacobian)记为矩阵 Df(x) \in \R^{m\times n}f:Rn→Rm,且…...

【蓝桥杯每日一题】递推算法

&#x1f34e; 博客主页&#xff1a;&#x1f319;披星戴月的贾维斯 &#x1f34e; 欢迎关注&#xff1a;&#x1f44d;点赞&#x1f343;收藏&#x1f525;留言 &#x1f347;系列专栏&#xff1a;&#x1f319; 蓝桥杯 &#x1f319;我与杀戮之中绽放&#xff0c;亦如黎明的花…...

Unity性能优化: 性能优化之内存篇

前言 本文和传统的内存优化不一样&#xff0c;不是讲如何降低内存占用&#xff0c;而是讲编程开发中要注意的内存问题以及一些内存技术的演变与原理。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点击进来一起交流一下开发经验呀 1: Application进程…...

华为OD机试题,用 Java 解【内存资源分配】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...

微服务之Nacos注册与配置

&#x1f3e0;个人主页&#xff1a;阿杰的博客 &#x1f4aa;个人简介&#xff1a;大家好&#xff0c;我是阿杰&#xff0c;一个正在努力让自己变得更好的男人&#x1f468; 目前状况&#x1f389;&#xff1a;24届毕业生&#xff0c;奋斗在找实习的路上&#x1f31f; &#x1…...

Android 动画详解

Android动画的分类与使用学习Android必不可少的就是动画的使用了&#xff0c;在Android版本迭代的过程中&#xff0c;出现了很多动画框架&#xff0c;这里做一个总结。Android动画类型分类逐帧动画【Frame Animation】&#xff0c;即顺序播放事先准备的图片。补间动画【Tween A…...

Linux -- 程序 进程 线程 概念引入

程序与进程 &#xff1a;程序 &#xff1a;什么是程序 &#xff1f;&#xff1f;&#xff1f;伪官方 &#xff1a; 二进制文件&#xff0c;文件存储在磁盘中&#xff0c;例如 /usr/bin 目录下 。 是静态。 简单讲 &#xff1a;# 我们都学习了语言&#xff0c;比如下面这串代…...

Android ART dex2oat

一、什么是dex2oat Dex2oat (dalvik excutable file to optimized art file) &#xff0c;是一个对 dex 文件进行编译优化的程序&#xff0c;在我们的 Android 手机中的位置是 /system/bin/dex2oat&#xff0c;对应的源码路径为 android/art/dex2oat/dex2oat.cc&#xff0c;通…...

「RISC-V Arch」RISC-V 规范结构

日期&#xff1a;20230228 规范分类 根据 RISC-V 设计哲学&#xff0c;其规范文档也是高度模块化的&#xff1a; ISA 规范&#xff08;2 篇&#xff09; 非特权规范特权规范 非 ISA 规范&#xff08;6篇&#xff09; Trace规范ABI 规范外部调试规范PLIC 规范SBI 规范UEFI 协…...

【C】线程控制

创建线程 #include <pthread.h>int pthread_create(pthread_t * thread,const pthread_attr_t * attr,void *(*start_routine)(void*), void * arg);返回值&#xff1a;成功返回0&#xff0c;失败返回错误号。 thread&#xff1a;成功返回后&#xff0c;新创建的线程的…...

Maven工程打jar包的N种方式

Maven工程打jar包 一、IDEA自带打包插件二、maven插件打包2.1 制作瘦包&#xff08;直接打包&#xff0c;不打包依赖包&#xff09;2.2 制作瘦包和依赖包&#xff08;相互分离&#xff09;2.3 制作胖包&#xff08;项目依赖包和项目打为一个包&#xff09;2.4 制作胖包&#xf…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...