数据结构(3)— 线性表之顺序存储详解介绍(含代码)
(1)博客代码在数据结构代码---GitHub仓库;
线性表介绍
线性表的基础概念
(1)甲骨文表示:线性表是零个或多个数据元素的有限序列。
(2)线性表,顾名思义,就是说这个数据存储是线性的。而线性的东西具有什么特征呢?
<1>数据是一对一的排列的,中间的数据都有且仅有一个前面数据(前面的数据叫做前驱)和一个后面的数据(后面的数据叫做后继)。而数据表的最前面的数据叫做表头,最尾端的数据叫做表尾。表头无前驱,表尾无后继。
<2>线性表是有限的。因为计算机的存储空间是有限的,所以线性表必然有限。
<3>线性表中的元素必须是相同类型。这个就像是我们在定义数组,一个数组中的元素,要么都是int型数据,要么都是char型数据,不可能数组中,第一个元素是int型数据,第二个元素变成了char型数据了。
(3)线性表的元素个数n(n>=0)表示线性表的长度,当n=0时,我们将这个表称之为空表。
(4)在非空表中,每个数据元素都有一个确定的位置,比如a1就是第一个数据元素,a2就是第二个数据元素,ai就是第i个数据元素。所以我们将i称为数据元素的位序。

一个数据元素可以拥有多个数据项
(1)我们上面看到,一个数据元素只有一个数据项。在数据结构(1)前言中我说了,一个数据元素可以有多个数据项,在研究数据结构时,我们都是着眼于数据元素。那有没有一个数据元素拥有多个数据项的线性表呢?有,我们常见的就是花名册。
(2)我们看到如下花名册里面,有姓名,性别,文化程度等等一些元素。这些元素就是数据项。而人具有这些元素,所以人这个个体就是数据元素。我们将这些人进行按照顺序排列,最后形成了花名册,这也叫做线性表。

线性表种类
(1)常见的线性表有:顺序存储(说白了就是数组),是链式存储,栈,队列。
(2)链式存储中又分为四种,单链表,静态链表,循环链表,双向链表。

线性表顺序存储介绍
顺序存储定义
定义
(1)定义:线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
(2)将上面这段话用白话文来说就是,线性表的顺序存储就是一个数组,不过与数组有些许不同,数据结构中的顺序存储定义需要增加一个length用于显示线性表的当前长度。
(3)这个时候可能会有人有疑惑了。为什么需要一个length呢?假设我们在排队买东西,由于空间的限制,只能来20个人(MAXSIZE)。而这个时候,排队的有5个人,如果有第6个人也要来排队,因为人很聪明,知道排到第五个人后面就可以了,但是在写程序的时候,你怎么知道需要将新来的数据放在哪里呢?如果不小心放在了第4个空间中,那么数据会被覆盖,出问题。放在第7位,那么第6位空着,浪费空间。
(4)线性表的顺序存储就是一个排队的过程,MAXSIZE用于定义这个队伍最大多长,而length用于指示当前位置排到哪里了。如果中间一个人突然走了,从这个人开始的后面所有人都要往前面移动,同时length要马上自减一次。如果有一个人因为紧急事件,不得不插队,从插队的位置往后移动,所有人都需要往后移动,length需要马上自增一次。
(5)因为按照编程习惯,我们的数组首元素下标为0。所以当线性表为空的时候,last为-1,而last=1时候,线性表长度=last+1=1!!!
#define success 0
#define fail -1
#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */typedef struct
{ElemType data[MAXSIZE]; /* 数组,存储数据元素 */int last; /* 线性表当前位置,last+1=length */
}SqList,*SqLink; /*SqList是定义线性表,SqLink是定义线性表的结构体指针*/
顺序存储方式和地址计算
其实如果学了C语言数组了,这部分没有什么可以说的。就是跟数组那样存储,是连续的。不清楚的自行去重新学习数组的知识。
数组长度与线性表长度区别
(1)我们上面说了,MAXSIZE是数组长度,这个规定了能够放进来多少数据,他的值是固定的。而length是线性表长度,他的长度是会随着线性表的删除,插入等操作发生改变,是动态的。任意时刻length<=MAXSIZE。
(2)至于为什么数组不改成动态分配,是因为这会带来性能上的消耗。我查了一些资料,以及问了bingAI,剥去关于没有及时释放不用的内存以外,更多的是malloc和free会造成资源消耗。


顺序存储实操
这里需要说的是,如果是操作成功了,返回0,操作失败返回-1。
#define success 0
#define fail -1
#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */typedef struct
{ElemType data[MAXSIZE]; /* 数组,存储数据元素 */int last; /* 线性表当前位置,last+1=length */
}SqList,*SqLink; /*SqList是定义线性表,SqLink是定义线性表的结构体指针*/创建顺序存储线性表
(1)我们先申请一个结构体指针,然后分配一个空间过来,如果没有分配成功,将会打印提示。
(2)如果创建成功之后,因为刚刚申请的空间中存放的值是未知的。所以按照习惯,我们一般都会将其设置为0。
(3)注意:memset函数必须写在 L -> length = -1; 前面,因为memset这一步,会将 L -> length 变成0。因为按照数组下标的习惯,0表示首元素地址,所以当线性表为空的时候,length==-1。(可能在部分教材里面length=0表示线性表为空,所以下面关于length部分代码会有所差异,需要注意)
/*作用: 创建线性表*传入参数:无*返回参数:创建失败打印错误报告,创建成功返回创建线性表的结构体指针*/
SqLink list_create(void)
{//建立线性表SqLink L;L = (SqLink)malloc(sizeof(SqList));//确认线性表是否存在if(L == NULL){printf("list malloc failed!\n");return L;}//线性表存在,将其内容清空//注意,这两句别写反了,否则last会变成0。memset(L , 0 , sizeof(SqList));L -> last = -1; //last表示线性表的指向位置,因为在C语言中,下标是从0开始,所以当为空表是last=-1//返回线性表return L;
}判断线性表是否存在
判断线性表是否存在,我们可以检测他指向的地址是否有问题。
/*作用: 判断线性表是否存在*传入参数:* @L: 线性表的结构体指针*返回参数:线性表不存在返回fail,线性表存在返回success*/
int list_if_exist(SqLink L)
{if(L==NULL){printf("list is not exist!\n");return fail;}return success;
}删除线性表
(1)如果线性表为NULL,表示传入线性表不存在,打印提示。
(2)如果线性表存在,将释放内存,同时将指针指向NULL。
/*作用: 删除线性表*传入参数:* @L: 线性表的结构体指针*返回参数:线性表不存在返回fail,线性表成功删除返回success*/
int list_delete(SqLink L)
{if(L==NULL){printf("list is not exist!\n");return fail;}free(L);L=NULL;return success;
}清空线性表
解析看创建顺序存储线性表。
/*作用: 清空线性表*传入参数:* @L: 线性表的结构体指针*返回参数:成功返回succes,失败返回fail*/
int list_clear(SqLink L)
{//确认线性表是否存在if(L == NULL){printf("list is not exist!\n");return fail;}//线性表存在,将其内容清空//注意,这两句别写反了,否则last会变成0。memset(L , 0 , sizeof(SqList));L -> last = -1; //last表示线性表的指向位置,因为在C语言中,下标是从0开始,所以当为空表是last=-1return success;
}判断线性表是否为空
(1)先判断线性表是否存在
(2)我们只需要判断length即可。如果对于length是什么依旧不清楚的,看下图。
/*作用: 判读线性表是否为空(因为使用者并不知道函数实现具体细节,所以需要加上这个)*传入参数:* @L: 线性表的结构体指针*返回参数:线性表为空返回succes,否则返回fail*/
int list_if_empty(SqLink L)
{//确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}if(L -> last ==-1){printf("list is empty!\n");return success;}return fail;
}
获取当前线性表长度
获取线性表长度就看length+1即可。
/*作用: 查看当前线性表长度*传入参数:* @L: 线性表的结构体指针*返回参数:返回当前线性表的长度*/
int list_get_length(SqLink L)
{//确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}return (L->last+1);
}判断指定数值是否在线性表中
(1)先判断线性表是否存在
(2)我们只需要将线性表中的值一个一个的与value对比即可。
/*作用: 判断value是否在线性表中*传入参数:* @L:线性表的结构体指针* @value:需要查看线性表中是否存在的值* @可输入值范围受到ElemType决定*返回参数:value在线性表中存在返回succes,value不在线性表中或线性表不存在返回fail*/
int list_value_if_locate(SqLink L,ElemType value)
{int i;//确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//逐个判断线性表中的值for(i = 0;i<=L->last;i++){if(L->data[i]==value){return success;}}return fail;
}在线性表指定位置插入数据
(1)判断线性表是否存在
(2)先判断线性表是否已经满了
(3)判断插入位置是否合理
(4)将要插入的位置元素都向后移动,腾出空间,让新数据插入
(5)插入新数据,last自增
/*作用: 插入数据,在线性表L的pos处插入数据value*传入参数:* @L: 线性表的结构体指针* @value: 需要插入线性表的值* @可输入值范围受到ElemType决定* @pos:需要插入的位置* @插入位置范围受到MAXSIZE限制*返回参数:返回当前线性表的长度*/
int list_insert(SqLink L,ElemType value,int pos)
{int i; //确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//如果线性表满了if(L->last == MAXSIZE-1){printf("list is full\n");return fail;}//判断插入的位置是否合法if(pos<0 || pos > L->last+1){printf("pos is invaild\n");}//向后移动for(i = L -> last;i >= pos;i--){L->data[i+1]=L->data[i];}//更新last和插入部分数值L->data[pos]=value;L->last++;return success;
}删除指定位置元素
(1)检查线性表是否存在
(2)是否为空表
(4)删除位置是否合理
(5)将所有数据向前移动(此时原来pos位置的数据会被pos+1处覆盖)
(6)last自减
/*作用: 删除指定位置的元素*传入参数:* @L: 线性表的结构体指针* @pos: 需要删除的数据的位置* @插入位置范围受到MAXSIZE限制*返回参数:删除失败返回fail,成功删除返回success*/
int list_delete_pos_value(SqLink L,int pos)
{int i;//确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//检测是否为空表if(L->last==-1){printf("list is empty!\n");return fail;}//检测删除位置是否合理if(pos < 0 || pos > L->last){printf("pos is invalid!\n");return fail;}//向前移动for(i=pos+1;i<=L->last;i++){L->data[i-1]=L->data[i];}//更改lastL->last--;return success;
}获取两个线性表的并集
(1)判断三个线性表是否存在
(2)判断他们是否为空
(3)先将L1的值存入L3中
(4)然后将L2中拥有,但是L1中没有的值存入L3中
/*作用: L1和L2并集,将并集值给到L3*传入参数:* @L1,L2: 两个不同的线性表* @L3: L1和L2并集*返回参数:失败返回fail,成功返回success*/
int list_merge(SqLink L1,SqLink L2,SqLink L3)
{int i;//判断L1,L2,L3是否存在list_if_exist(L1);list_if_exist(L2);list_if_exist(L3);//判断L1,L2,是否为空list_if_empty(L1);list_if_empty(L2);//将L1中的所有元素存放到L3中for(i = 0; i <= L1->last;i++){list_insert(L3, L1->data[i],L3->last+1);}for(i = 0; i <= L2->last;i++){//判读L2中的每一个元素是否在L1中,如果不在,就存入到L3中if(list_value_if_locate(L1,L2->data[i])==-1){//如果L3满了,提前结束if(list_insert(L3,L2->data[i],L3->last+1)==fail){return fail;}}}return success;
}删除线性表中重复元素
(1)判断线性表是否存在
(2)如果只有一个元素就不需要判断
(3)我们选择从第二个元素开始(建立变量i),判断i位置的元素是否与i前面元素有重复,如果重复了,那么就删除i位置的元素。此时可以跳出循环。
(4)因为删除位置i的元素之后,原来位置i+1的元素会替补到位置i处。所以我们需要先将位置i自减一次,然后在for语句中自增一次,为了保持位置i不变,所以我们需要i自减一次抵消。
(5)如果没有重复元素,那么i就自增。



/*作用:删除线性表中重复元素*传入参数:* @L1 : 线性表的结构体指针*返回参数:删除成功返回success*/
int list_purge(SqLink L)
{int i,j;//确认线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//如果当前线性表只有一个元素,就没有必要判断了if(L->last==0){return success;}//让i不断向后移动for(i=1;i<=L->last;i++){//将位置i之前的元素与i处元素进行判断,相同就删除for(j=i-1;j>=0;j--){//如果发现前面有与位置i相同的元素,删除,保持i不动if(L->data[i]==L->data[j]){//位置i与前面有重复,就删除位置i的值list_delete_pos_value(L,i);//因为需要保持位置i不动,而for语句中有i++,所以这里用i--抵消i--;break;}}}return success;
}获取指定位置元素
(1)判断线性表是否存在
(2)判断是否为空表
(3)判断获取数据的位置是否合理
(4)返回指定位置值
/*作用: 返回指定位置的值*传入参数:* @L: 线性表的结构体指针* @pos:指定位置* @插入位置范围受到MAXSIZE限制*返回参数:线性表为空,返回fail。成功打印返回success*/
int list_pos_value(SqLink L,int pos)
{//判断线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//判断是否为空表if(L->last==-1){printf("list is empty!\n");}//判断获取数据的位置是否合法if(pos<0 || pos > L->last+1){printf("pos is invaild\n");}//返回指定位置值return (L->data[pos]);
}显示线性表中的值
(1)线性表是否存在
(2)是否为空表
(3)逐个打印线性表中的元素
/*作用: 显示线性表中的值*传入参数:* @L: 线性表的结构体指针*返回参数:线性表为空,返回fail。成功打印返回success*/
int list_show(SqLink L)
{int i;//判断线性表是否存在if(L==NULL){printf("list is not exist!\n");return fail;}//判断是否为空表if(L->last==-1){printf("list is empty!\n");}//将线性表中的值打印出来for(i=0;i<=L->last;i++){printf("%d ",L->data[i]);}printf("\n");return success;
}线性表顺序结构优缺点
优点
(1)存储密度高
(2)查找线性表中元素也方便
缺点
(1)需要提供一大片较大的连续存储空间。
(2)插入,删除等运算耗时,存在元素在存储空间成片移动的现象
总结
如果我们需要插入删除操作比较多,比如游戏开发中的装备经常会更换,这个用线性存储就非常不合适,链式存储就比较好。但是如果我们需要频繁查找元素,比如查找游戏ID,查看用户性别等等用顺序存储就很方便。
相关文章:
数据结构(3)— 线性表之顺序存储详解介绍(含代码)
(1)博客代码在数据结构代码---GitHub仓库;线性表介绍线性表的基础概念(1)甲骨文表示:线性表是零个或多个数据元素的有限序列。(2)线性表,顾名思义,就是说这个…...
ChatGPT正当时,让我们一起深耕智能内容生成和智能内容增强领域
ChatGPT以其强大的信息整合和对话能力惊艳了全球,在自然语言处理上面表现出了惊人的能力。很多人都预测 2023 年将是 AI 生成之年,也许我们将迎来继农业革命、工业革命以来的第三种通用技术的普及。 信必优长期专注于人工智能领域,拥有产品研…...
天梯赛训练L1-019 (谁先倒)
目录 1、L1-019 谁先倒 2、如果帮到大家,请大家一键三连!!! 3、读书吧,在落幕无光时找到方向!!! 1、L1-019 谁先倒 分数 15 题目通道 划拳是古老中国酒文化的一个有趣的组成部分…...
MySQL DQL语句基础(一)
目录 DQL 基本语法 基础查询 1、查询多个字段 2、字段设置别名 3、去除重复记录 条件查询 语法 条件 案例 聚合函数 常见的聚合函数 语法 DQL DQL英文全称是Data Query Language(数据查询语言),数据查询语言,用来查询数据库中表的记录。 基…...
ccc-pytorch-LSTM(8)
文章目录一、LSTM简介二、LSTM中的核心结构三、如何解决RNN中的梯度消失/爆炸问题四、情感分类实战(google colab)一、LSTM简介 LSTM(long short-term memory)长短期记忆网络,RNN的改进,克服了RNN中“记忆…...
教育小程序开发解决方案
如今无论是国家还是家庭对于教育的重视性也越来越高,都希望自己的孩子能够赢在起跑线上,但是因为工作的缘故许多家长并没有过多的精力去辅导孩子学习,再加上许多家长对于教育也并没有经验与技巧。而这些都充分体现了正确教育的重要性。 那么一…...
动态规划之股票问题大总结
参考资料:代码随想录 (programmercarl.com)一、只能买卖一次题目链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)算法思想:设置两种状态:0表示已持有股票,1表示未持有股票1.dp[i][0]表示第i天已持有股票时&…...
我来跟你讲vue进阶
一、组件(重点) 组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象…...
#847(Div3)E. Vlad and a Pair of Numbers
原题链接: E. Vlad and a Pair of Numbers 题意: 题目有公式 a⊕b(ab)/2xa ⊕ b (a b) / 2 xa⊕b(ab)/2x, 给你的是 xxx,让输出一组满足题目要求的 a,ba,ba,b,没有就输出−1-1…...
怎么把pdf转换成图片?这个方法你值得拥有
想要高效率的工作,除了需要大家合理安排时间之外,一些能够辅助高效工作的工具也是必不可少的。就拿要把一份pdf文件转换成若干图片来说,如果不知道方法,找不到合适的转换工具,那么想要完成这一任务,势必要花…...
go语言使用append向二维数组添加一维数组
var ans [][]int ans append(ans, append([]int(nil), nums...))(正确写法)需要注意的是,为了避免对原切片造成影响,代码在将当前排列追加到结果数组 ans 时,使用了 append(ans, append([]int(nil), nums…)) 的方式…...
YOLOv5训练大规模的遥感实例分割数据集 iSAID从切图到数据集制作及训练
最近想训练遥感实例分割,纵观博客发现较少相关 iSAID数据集的切分及数据集转换内容,思来想去应该在繁忙之中抽出时间写个详细的教程。 iSAID数据集下载 iSAID数据集链接 下载上述数据集。 百度网盘中的train和val中包含了实例和语义分割标签。 上述…...
js学习5(函数)
目录 定义函数 函数的特性 使用函数模拟类 模拟私有属性和方法 闭包 函数特性利用 箭头函数 定义函数 function func1(name) { console.log(name); } func2 function (name) { console.log(name); } func3 function func0(name) { console.log(name); } co…...
用Qt画一个仪表盘
关于Qt Qt是一个跨平台的C图形用户界面应用程序框架,通过使用Qt,可以快速开发出跨平台的多平台应用程序,包括Windows、Mac OS X、Linux和其他Unix系统。Qt提供了强大的图形操作界面(GUI)程序开发和移植的能力…...
linux 端口查询命令
任何知识都是用进废退,有段时间没摸linux,这大脑里的知识点仿佛全部消失了,就无语。 索性,再写一篇记录,加强一下记忆,下次需要就看自己的资料好了。lsof命令Linux端口查询命令可以通过lsof实现:…...
C语言函数: 字符串函数及模拟实现strtok()、strstr()、strerror()
C语言函数: 字符串函数及模拟实现strtok()、strstr()、strerror() strstr()函数: 作用:字符串查找。在一串字符串中,查找另一串字符串是否存在。 形参: str2在str1中寻找。返回值是char*的指针 原理:如果在str1中找到了str2&…...
【学习笔记】人工智能哲学研究:《心智、语言和机器》
关于人工智能哲学,我曾在这篇文章里 【脑洞大开】从哲学角度看人工智能:介绍徐英瑾的《心智、语言和机器》 做过介绍。图片来源:http://product.dangdang.com/29419969.html在我完成了一些人工智能相关的工作以后,我再来分享《心智…...
设计模式之门面模式(外观模式)
目录 1.模式定义 2.应用场景 2.1 电源总开关例子 2.2 股民炒股场景 编辑 3. 实例如下 4. 门面模式的优缺点 传送门: 项目中用到的责任链模式 给对象讲工厂模式,必须易懂易会 策略模式,工作中你用上了吗? 1.模式定…...
MySQL - 多表查询
目录1. 多表查询示例2. 多表查询分类2.1 等/非等值连接2.1.1 等值连接2.1.2非等值连接2.2 自然/非自然连接2.3 内/外连接2.3.1 内连接2.3.2 外连接3.UNION的使用3.1 合并查询结果3.1.1 UNION操作符3.1.2 UNION ALL操作符4. 7种JOIN操作5. join 多张表多表查询,也称为…...
自定义报表是什么?
自定义报表是指根据用户的需求和要求,自行设计和生成的报表。自定义报表可以根据用户的具体需求,选择需要的数据和指标,进行灵活的排列和组合,生成符合用户要求的报表。自定义报表可以帮助用户更好地了解业务情况,发现…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
