菜鸡的Java笔记第二十七java链表基本概念SilentKiller

链表基本概念1.链表的基本形式2.单向链表的完整实现认识链表链表=可变长的对象数组,属于动态对象数组的范畴链表是一种最简单的线性数据结构,之所以会存在有数据结构问题主要是解决亮点:存储的数据不受限制,查找速度快对象数组有那些问题呢?对象数组可以保存一组对象方便开发对象数组的长度固定,而且数据的删除,修改,增加处理麻烦所有的开发之中都100%不可能避免掉对象数组的使用正因为如此现在如果要想让其可以编写出便于维护的代码,那么就需要实现一个动态对象数组,那么就可以使用链表完成但是现在如果要想实现动态的对象数组,要考虑两个问题:为了适应于所有的开发要求,此对象数组要求可以保存所有的数据类型,那么一首选Object类型为了可以保存多个数据,需要采用引用的方式来进行保存,但是数据本身是不可能保存顺序的所以需要有一个可以负责保存顺序的类来包装这个数据分析结论:保存数据为了方便使用Object数据本身不包含有先后的逻辑关系,所以将数据封装在一个Node类,负责关系的维护范例:定义出如下的一个类

classNode{//b表示定义的节点privateObjectdata;//要保存的数据privateNodenext;//保存下一个节点publicNode(Objectdata){//有数据才可以保存节点this.data=data;}publicvoidsetNext(Nodenext){//设置节点this.next=next;}publicNodegetNext(){//取得节点returnthis.next;}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}完成节点之后,下面就可以进行节点的基本使用了范例:采用循环的方式操作节点

classNode{//b表示定义的节点privateObjectdata;//要保存的数据privateNodenext;//保存下一个节点publicNode(Objectdata){//有数据才可以保存节点this.data=data;}publicvoidsetNext(Nodenext){//设置节点this.next=next;}publicNodegetNext(){//取得节点returnthis.next;}publicObjectgetData(){returnthis.data;}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){//1.定义各自独立的操作节点Noderoot=newNode("火车头");Noden1=newNode("车厢1");Noden1=newNode("车厢2");//2.设置彼此间的关系root.setNext(n1);n1.setNext(n2);//3.输出NodecurrentNode=root;//从根节点开始取出数据while(currentNode!=null){System.out.println(currentNode.getData());//取出数据currentNode=currentNode.getNext();//下一个节点}}}以上的操作如果使用循环并不方便。最好的做法是递归调用范例:利用递归的方式实现内容的取得

classNode{//b表示定义的节点privateObjectdata;//要保存的数据privateNodenext;//保存下一个节点publicNode(Objectdata){//有数据才可以保存节点this.data=data;}publicvoidsetNext(Nodenext){//设置节点this.next=next;}publicNodegetNext(){//取得节点returnthis.naxt;}publicObjectgetData(){returnthis.data;}}classlink{//表示一个链表操作类,利用此类来隐藏Node的节点匹配publicvoidadd(Objectobj){//向链表里面追加数据}publicvoidprint(){//输出链表中的全部数据}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){Linkall=newLink();all.add("商品1");all.add("商品2");all.add("商品3");all.print();}}用户不关心Node,用户只关心通过Link操作完成后可以取得数据范例:完善程序

classLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}}//************************************privateNoderoot;//根元素}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}如果要开发程序,那么一定要创建自己的操作标准,那么一旦说到标准就应该想到使用接口来完成

interfaceLink{}classLinkImplimplementsLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}}//************************************privateNoderoot;//根元素}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}在随后完善代码的过程之中,除了功能的实现之外,实际上也属于接口功能的完善实现数据增加操作publicvoidadd(Objectdata)1.需要在接口里面定义好数据增加的操作方法

interfaceLink{publicvoidadd(Objectdata);//数据增加}classLinkImplimplementsLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}}//************************************privateNoderoot;//根元素}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}2.进行代码的实现,同样实现的过程之中LinkImpl类只关心根节点,而具体的子节点的排序都交由Node类负责处理在Link类中实现add()方法:

interfaceLink{publicvoidadd(Objectdata);//数据增加}classLinkImplimplementsLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}}//************************************privateNoderoot;//根元素publicvoidadd(Objectdata){if(data==null){//现在没有要增加的数据return;//结束调用}NodenewNode=newNode(data);//创建新的节点if(this.root==null){//保留有根节点this.root=root;}else{//应该交由Node类负责处理this.root.addNode(newNode);}}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}在Node类中进行数据的追加操作:

interfaceLink{publicvoidadd(Objectdata);//数据增加}classLinkImplimplementsLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}publicvoidaddNode(NodenewNode){if(this.next==null){this.next=newNode;}else{this.next.addNode(newNode);}}}//************************************privateNoderoot;//根元素publicvoidadd(Objectdata){if(data==null){//现在没有要增加的数据return;//结束调用}NodenewNode=newNode(data);//创建新的节点if(this.root==null){//保留有根节点this.root=root;}else{//应该交由Node类负责处理this.root.addNode(newNode);}}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}此时的代码实现过程与基本的实现是完全一样的取得保存元素个数:publicintsize()每个Link接口的对象都要保存各自的内容,所以为了方便控制保存个数,可以增加一个Link类中的属性,并且用此属性在数据成功追加之后实现自增操作在Link类中定义一个count属性,默认值为:0

interfaceLink{publicvoidadd(Objectdata);//数据增加}classLinkImplimplementsLink{//外部的程序只关心此类privateclassNode{//使用私有内部类,防止外部使用此类privateObjectdata;privateNodenext;publicNode(Objectdata){this.data=data;}publicvoidaddNode(NodenewNode){if(this.next==null){this.next=newNode;}else{this.next.addNode(newNode);}}}//************************************privateNoderoot;//根元素privateintcount=0;//当数据已经成功添加完毕之后实现计数的统计publicvoidadd(Objectdata){if(data==null){//现在没有要增加的数据return;//结束调用}NodenewNode=newNode(data);//创建新的节点if(this.root==null){//保留有根节点this.root=root;}else{//应该交由Node类负责处理this.root.addNode(newNode);}this.count++;//当节点保存完毕之后就可以进行数据增加了}}publicclasslinkedList{publicstaticvoidmain(Stringargs[]){}}而在Link接口里面追加size()的方法,同时在LinkImpl子类里面进行方法的覆写

interfaceLink{publicvoidadd(Objectdata);//数据增加publicintsize();//取得保存元素的个数publicbooleanisEmpty();//判断是否为空集合}范例:在LinkImpl类中实现此方法

interfaceLink{publicvoidadd(Objectdata);//数据增加publicintsize();//取得保存元素的个数publicbooleanisEmpty();//判断是否为空集合publicbooleancontains(Objectdata);//判断是否有指定的元素}2.在LinkImpl子类里面要通过根元素开始调用查询,所有的查询交由Node类负责在LinkImpl发出具体的查询要求之前,必须要保证有集合数据

publicbooleancontains(Objectdata){if(this.root==null){//没有集合数据returnfalse;}returnthis.root.containsNode(data);//根元素交给Node类完成}在Node类中实现数据的查询

publicObjectgetNode(intindex){//传递索引的序号if(LinkImpl.this.foot++==index){//当前的索引为要查找的索引returnthis.data;//返回当前节点对象}else{returnthis.next.getNode(index);}}在Link类中实现get()方法

publicObjectget(intindex){if(index>=this.count){//索引不存在returnnull;}this.foot=0;//查询之前执行一次清零操作returnthis.root.getNode(index);}

这种查询的模式与contains()最大的不同一个是数字索引,一个是内容修改数据:publicvoidset(intindex,Objectobj)与get()相比set()方法依然需要进行循环的判断,只不过get()索引判断成功之后会返回数据,而set()只需要用新的数据更新已有节点数据即可1.在Link接口里面创建一个新的方法publicvoidset(intindex,Objectobj)2.修改LnikImopl子类,流程与get()差别不大:在Node类里面追加一个新的setNode()方法;

publicvoidsetNode(intindex,Objectobj){if(LinkImpl.this.foot++==index){this.obj=obj;//重新保存数据}else{this.next.setNode(index,obj);}}在LinkImpl子类里面覆写set()方法,在set()方法编写的时候也需要针对于给定的索引进行验证

publicvoidset(intindex,Objectobj){if(index>=this.count){//索引不存在returnnull;}this.foot=0;//查询之前执行一次清零操作this.root.setNode(index,obj);}set()与get()方法实际上在使用时都有一个固定的条件:集合中的保存数据顺序应该为添加顺序数据删除:publicvoidremove(Objectobj)如果要进行数据的删除,那么对于整个链表而言就是节点的删除操作而节点的删除操作过程之中需要考虑的问题是什么?要删除的是根节点还是子节点问题1.要删除的是根节点:Link类处理,因为根节点有关的所有节点都应该交由Link类管理Link.root=Link.root.next2.要删除的是子节点:交由Node类负责处理删除节点的上一个节点.next=删除节点.next1.在Link接口里面创建一个新的方法publicvoidremove(Objectdata);//删除数据2.修改LnikImopl类的操作:在Node类中增加一个removeNode()的方法

//第一次:this.LinkImpl.root.next,previous=LinkImpl.root;//第二次:this.LinkImpl.root.next.next,previous=LinkImpl.root.nextpublicvoidremove(Nodeprevious,Objectdata){if(this.data.equals(data)){previous.next=this.next;//空出当前节点}else{this.next.removeNode(this,data);}}在Link类中增加新的操作:

publicvoidremove(Objectdata){if(this.contains(data)){//数据如果存在则删除if(this.root.equals(data)){//根元素为要删除的元素this.root=this.root.next;//第二个元素作为根元素}else{//不是根元素,根元素一斤判断完了this.root.next.removeNode(this.root,data);}this.count--;}}整个删除操作很好的体现了this的特性contains()和remove()方法必须有对象比较的支持,对象比较使用的就是Object类中的equals()方法清空链表:publicvoidclear()当链表中的数据不需要在使用的时候,那么可以进行清空,而清空最简单的做法就是将root设置为null1.在Link接口里面创建一个新的方法publicvoidclear();//清空链表2.直接在LinkImpl类中修改清空操作

publicvoidclear(){this.foot=null;this.count=0;//元素的保存个数清0System.gc();//回收内存空间}实际上这种代码还欠缺一个很好的内存释放问题返回数据:publicObject[]toArray()恒定的概念:链表就是动态对象数组,但是要想操作链表中的数据,那么最好的做法是将其转换为对象数组返回所以这个时候就需要针对数据做递归处理1.在Link接口里面定义返回对象数组的方法publicObject[]toArray()2.修改LnikImopl子类由于Node类需要操作链表数据读取,所以应该在LinkImpl子类里面应该提供有一个对象数组的属性publicObjectretData[]=null;在LinkImpl子类里面覆写toArray()方法,并且要根据长度开辟数组空间

publicObject[]toArray(){if(this.root==null){returnnull;}this.retData=newObject[this.count];this.foot=0;this.root.toArrayNode();returnthis.retData;}

在Node类里面实现数据的保存操作

publicvoidtoArrayNode(){LinkImpl.this.retData[LinkImpl.this.foot++]=this.data;if(this.next!=null){this.next.toArrayNode();}}不过以上的设计都没有考虑过性能问题

publicObject[]toArray(){if(this.root==null){//现在没有数据returnnewObject[0];//没有数据返回}this.retData=newObject[this.count];//根据已有的数据个数开辟数组个数this.foot=0;//脚标重置this.root.toArrayNode();//交给Node类负责returnthis.retData;}3.真正获得数据的过程(节点迭代过程)应该有Node类负责

//第1次调用:this=LinkImpl.root9//第2次调用:this=LinkImpl.root.naxtpublicvoidtoArrayNode(){//递归调用LinkImpl.this.retData[LinkImpl.this.foot++]=this.data;if(this.naxt!=null){//还有下一个节点this.naxt.toArrayNode();}}综合实战:宠物商店接口实际上是属于某几类事物的抽象,也就是说在整个的定义结构上,接口标准应该优先于类定义出来,而后类按照指定的接口标准进行实现如果说现在有这样的一个案例要求:定义一个宠物商店,在这个宠物商店里面可以实现宠物的上架,下架,关键字查询现在假设宠物里面只包含两个信息(名字,年龄),而后要求通过类的结构关系描述出本程序宠物商店应该是一个程序类,因为宠物商店可能有很多种,但是其具备的特征肯定只有一个,而后宠物商店只与宠物标准有关(符合此标准的可能有多种宠物类型)而宠物商店里面需要保存有多中宠物信息(不知道个数的对象数组,应该采用链表实现)1.应该建立宠物的标准服务接口

interfacePet{publicStringgetName();publicintgetAge();}2.定义宠物商店,宠物尚待年不关心具体的宠物类型,只关心宠物标准

classPetShop{privateIlinkallPets=newLinkImpl();//动态对象数组publicvoidadd(Petpet){//追加的是宠物this.allPets.add(pet);//宠物信息追加}publicvoiddelete(Petpet){//删除宠物信息this.allPets.remove(pet);//equals()支持}publicILinksearch(StringkeyWord){//返回查询结果ILinkresult=newLinkImpl();//查询结果Objectdata[]=this.allPets.toArray();//变为对象数组返回for(intx=0;x

classDog{//狗privateStringname;privateintage;publicDog(Stringname,intage){this.name=name;this.age=age;}publicbooleanequals(Objectobj){if(this==obj){returntrue;}if(obj==null){returnfalse;}if(!(objinstanceofDog)){returnfalse;}Dogpet=(Dog)obj;returnthis.name.equals(pet.name)&&this.age==pet.age;}publicStringgetName(){returnthis.name;}publicintgetAge(){returnthis.age;}publicStringtoString(){return"【宠物狗】name="+this,name+",age="+this.age;}}classCat{privateStringname;privateintage;publicCta(Stringname,intage){this.name=name;this.age=age;}publicbooleanequals(Objectobj){if(this==obj){returntrue;}if(obj==null){returnfalse;}if(!(objinstanceofCat)){returnfalse;}Catpet=(Cat)obj;returnthis.name.equals(pet.name)&&this.age==pet.age;}publicStringgetName(){returnthis.name;}publicintgetAge(){returnthis.age;}publicStringtoString(){return"【宠物猫】name="+this,name+",age="+this.age;}}4.测试

publicclasslinkedList{publicstaticvoidmain(Stringargs[]){PetShopshop=newPetShop();//宠物商店准备好了shop.add(newDog("狗子",1));shop.add(newDog("二狗子",1));shop.add(newCat("喵喵",1));shop.add(newCat("小瞄",1));shop.delete(newDog("二狗子",1));//删除操作ILinkresult=shop.search("瞄");Objectdata[]=result.toArray();for(intx=0;x

THE END
1.QYFMC0012020宠物冻干零食执行标准.pdf本标准规定了宠物零食的要求、试验方法、检验规则、标志、包装、运输、贮存等内容。本 标准适用于以禽肉、畜肉、生皮、蔬菜、淀粉、植物蛋白为原料经烘干、压制。挤出成型的宠物 零食(以下简称为产品),有特殊要求 Q YFMC 001-2020宠物冻干零食执行标准 来自淘豆网www.taodocs.com转载请标明出处. ...https://www.taodocs.com/p-578778066.html
2.五一起,新动物防疫法实施!除了遛狗不栓绳,这些行为也要注意而且,考虑到伸缩牵引带的使用门槛,也不建议初学者使用。它更适合训练使用的工作犬远距离执行任务,普通的宠物主人不一定能做到让宠物犬稳定地随行。相比之下,项圈式的P链是更好的选择,胸背式的K9也有不少拥趸。 ■项圈式的P链 图片:网络 ■胸背式的K9 图片:网络 ...https://static.zhoudaosh.com/CBFC6EF8186E3FE2A9D575FF2D94464B3A252181568A8A34F22C5AA731B3A5AD
3.2024宠物寄养标准化协议.docx2024宠物寄养标准化协议本合同目录一览第一条宠物寄养服务内容1.1寄养宠物种类1.2寄养服务时间1.3寄养服务地点第二条宠物主人义务2.1提供宠物相关信息2.2遵守寄养规定2.3支付寄养费用第三条寄养方义务3.1提供安全的环境3.2按时提供宠物食物和水3.3定期带宠物锻炼和散步第四条宠物健康与保险4.1宠物主人需提供宠物健康证明4.2宠物...https://www.renrendoc.com/paper/359567724.html
1.首个宠物用品国家标准GB/T43839GB/T 43839-2024是首个针对宠物用品的推荐性国家标准。该标准将于2024年10月1日正式实施,该标准为中国市场上的一系列的宠物用品建立了标准化的质量和安全框架。http://www.sgsonline.com.cn/case/article/detail-4606.html
2.宠物行业宠物饲养与医疗服务标准66文库网(66wkw.com)宠物行业宠物饲养与医疗服务标准第1章宠物行业概述...https://m.66wkw.com/doc/138853.html
3.狗粮最新国家标准是什么狗粮主要执行标准简介 1、GB/T 31216-2014《全价宠物食品 犬粮》 是中国国家标准化管理委员会发布的关于全价宠物食品犬粮的标准。该标准规定了全价犬粮的分类、要求、试验方法、检验规则、标签、包装、运输和储存。适用于以谷物、肉类、蔬菜等为原料加工而成的全价犬粮,旨在保证犬粮的营养成分、卫生质量和安全性,满...https://www.qilaijian.com/hangye/27171.html
4.约翰农场——树立宠物零食“行业标准”的风向标界面新闻在国内,猫猫狗狗的零食,与我们人类零食有“质”的区别,区别在于宠物零食没有执行标准。有的铲屎官说不服:宠物零食背后明明清晰的写着:Q/2333,Q/6666…… 因目前国家尚未出台宠物零食的相应执行标准,行业内也没有出现“领头羊”来带头制定行业标准。所以,Q开头的编码通常为企业执行标准,是按照企业的需求与标准制定...https://www.jiemian.com/article/9007524.html
5....禁止携带宠物家禽等动物乘车,但正在执行公务的专用动物以及...根据《乘车规则》,禁止携带()、()、()、()、()等危险品和有刺激性气味、()、尖锐物品以及宠物等易造成车站、列车污损的物品进站、乘车。 根据《乘车规则》,禁止携带()、()、()、()、()等危险品和有刺激性气味、()、尖锐物品以及宠物等易造成车站、列车污损的物品进站、乘车。 https://www.educity.cn/souti/twbm4qzd.html
6.面向对象程序设计Java实验(黑龙江大学)黑龙江大学java实验讲义●评分标准:满分10分 按要求正确完成所有任务(4项任务各2分,合计8分) 编码、调试操作熟练;输出正确,界面符合要求(1分) 实验报告撰写规范,内容完整;(1分) ●测试案例: 表1.1 测试案例(仅用于编码测试) ●思考题 如果阶乘结果溢出,该怎么办? 若要输出如下乘法口诀表,该如何修改代码? https://blog.csdn.net/weixin_61034701/article/details/133612689
7.讨论科普国内宠物食品检测标准现状目前并没有现行的宠物食品强制性标准,有一个2007年审查至今的《宠物食品卫生标准》。 目前对入境宠物食品检验检疫标准只有一个行业标准,并不涉及到相关化学指标的检测。 图片中还有两个为出口标准,一个为饼干类,一个为烘干禽肉类(注意了,不涉及冻干,罐头等) ...https://www.douban.com/group/topic/298553496/
8.宠物食品法规标准培训——试题2、宠物食品分类包括( ) A 宠物配合饲料B 宠物添加剂预合混饲料C 其它宠物饲料D 宠物饲料添加剂 3、宠物食品的质量卫生指标应符合以下法规、标准等要求 ( ) A 产品标签标示B 《宠物饲料卫生规定》C 执行标准D 《饲料卫生标准》 4、宠物食品中哪些卫生指标的检测结果不是以88%计 ( ) ...https://www.wjx.cn/xz/266980854.aspx
9.最新资讯!CTI参与起草我国首个宠物用品安全标准2024年3月15日,中国首个针对宠物用品安全的推荐性国家标准GB/T 43839-2024《伴侣动物(宠物)用品安全技术要求》正式发布,将于今年10月1日正式实施。受全国伴侣动物(宠物)标准化技术委员会邀请,CTI华测检测参与了本标准的起草工作。该标准填补了我国宠物用品行业安全标准的空白,为宠物用品企业提供了执行标准。 https://www.cti-cert.com/new/25777.html
10.《国民经济行业分类》(GB/T47542017)2019年修改版GB/T 4754-2017《国民经济行业分类》国家标准第1号修改单(以下简称第1号修改单)已经国家标准化管理委员会于2019年3月25日批准,自2019年3月29日起实施。 为确保统计调查工作严格执行国家标准,经研究决定,新制定或修订的统计调查制度要严格执行第1号修改单。目前正在执行的统计调查制度从其规定。 https://www.shangyexinzhi.com/article/4707342.html