第五天 面向对象3.docx
- 文档编号:23139172
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:58
- 大小:880.28KB
第五天 面向对象3.docx
《第五天 面向对象3.docx》由会员分享,可在线阅读,更多相关《第五天 面向对象3.docx(58页珍藏版)》请在冰豆网上搜索。
第五天面向对象3
第五天面向对象_04
3.1、链表(理解)
链表是一种最基本的数据结构,但是对于数据结构的部分,强调以下几点:
· 在整个Java开发领域之中,没有一本真正去讲解数据结构的书,只能去看C语言的数据结构;
· 在所有的开发之中,都会存在数据结构的身影,可以这样去解释:
数据结构的精通与否,完全决定于以后;
· 数据结构的核心:
引用数据类型操作。
3.1.1 、链表的基本概念
链表实际上可以理解为一串数据,或者按照专业性的说法,可以理解为动态的对象数组,对象数组最大优点:
是表示出多的概念,例如:
多个雇员。
但是传统的对象数组有一个最大的问题在于,里面保存的数据的长度是固定的。
思考:
如果说现在要想扩大一个对象数组的范围?
· 建立一个新的对象数组,而后将原本的内容拷贝到新数组之中,再改变原数组的引用方式。
publicclassTestDemo{
publicstaticvoidmain(Stringargs[]){
String[]str=newString[]{"Hello","World","MLDN"};
String[]newStr=newString[6];
System.arraycopy(str,0,newStr,0,str.length);
str=newStr; // 改变引用,存在垃圾
str[3]="你好";
str[4]="世界";
for(intx=0;x System.out.println(str[x]); } } } 通过以上的分析,可以发现,对象数组所有的对象元素被数组的索引控制,可以说是自动完成的控制,但是链表需要人为进行关系的设置,而且每个操作设置的时候,除了要保存“对象”之外,还要再多保留一个引用。 这个引用就和之前讲解的领导是一样的: 一个雇员的领导还是雇员,雇员领导的领导也是雇员。 范例: 先给出链表的基本操作结构 classNode{ privateStringdata; // 假设要保存的数据类型是字符串 privateNodenext; publicNode(Stringdata){ this.data=data; } publicStringgetData(){ returnthis.data; } publicvoidsetNext(Nodenext){ this.next=next; } publicNodegetNext(){ returnthis.next; } } 范例: 挂节点 publicclassTestDemo{ publicstaticvoidmain(Stringargs[]){ //1、设置数据 Noden1=newNode("火车头"); Noden2=newNode("车厢A"); Noden3=newNode("车厢B"); n1.setNext(n2); n2.setNext(n3); //2、取出数据 NodecurrentNode=n1; // 设置每一个当前节点 while(currentNode! =null){ // 有节点存在 System.out.println(currentNode.getData()); // 当前节点内容 currentNode=currentNode.getNext(); } } } 但是这样的方式来输出所有的节点的配置过程,发现并不是特别好,这种输出的操作,应该采用递归合适。 publicclassTestDemo{ publicstaticvoidmain(Stringargs[]){ //1、设置数据 Noden1=newNode("火车头"); Noden2=newNode("车厢A"); Noden3=newNode("车厢B"); n1.setNext(n2); n2.setNext(n3); //2、取出数据 print(n1); } publicstaticvoidprint(Nodenode){ // 取出节点内容 System.out.println(node.getData()); if(node.getNext()! =null){ // 后面还有货 print(node.getNext()); // 向下 } } } 可以发现,整个一链表的关键是在于Node节点的关系匹配上。 3.1.2 、链表的基本雏形 通过之前的分析,可以发现链表的最大作用的类就是Node,但是以上程序都是由用户自己去匹配节点关系的,但是这些节点的匹配工作不应该由用户完成,应该由一个程序专门负责。 那么专门负责这个节点操作的类,就称为链表类 —— Link,负责处理节点关系,而用户不需要关心节点问题,只需要关心Link的处理操作即可。 范例: 开发Link类 classNode{ privateStringdata; // 假设要保存的数据类型是字符串 privateNodenext; publicNode(Stringdata){ this.data=data; } publicStringgetData(){ returnthis.data; } publicvoidsetNext(Nodenext){ this.next=next; } publicNodegetNext(){ returnthis.next; } publicvoidaddNode(NodenewNode){ // 操作的是节点关系 if(this.next==null){ // 当前节点的next为null this.next=newNode; // 保存新节点 }else{ this.next.addNode(newNode); } } publicvoidprintNode(){ System.out.println(this.data); if(this.next! =null){ // 还有下一个节点 this.next.printNode(); } } } classLink{ // 处理节点关系 privateNoderoot; // 根节点 publicvoidadd(Stringdata){ // 处理数据保存 if(data==null){ // 没有数据 return; // 直接返回 } // 每一个数据如果要想保存在链表之中,必须将其封装为节点 // 这一操作的过程外部(用户)不需要知道 NodenewNode=newNode(data); if(this.root==null){ // 现在没有根节点 this.root=newNode; // 第一个作为根节点 }else{ this.root.addNode(newNode); } } publicvoidprint(){ if(this.root! =null){ // 现在有根节点 this.root.printNode(); //Node类处理 } } } publicclassTestDemo{ publicstaticvoidmain(Stringargs[]){ Linkall=newLink(); all.add("Hello"); all.add("World"); all.add("MLDN"); all.print(); } } 通过以上的代码可以发现,Link类处理节点的操作,而Node类负责节点的具体顺序的操作,但是客户端,不关心节点,只关心Link类即可。 3.1.3 、开发可用链表 3.1.3 .1、增加数据: publicStringadd(数据 对象) 通过上面的程序分析,可以发现,对于链表实现,Node类是整个操作的关键,但是首先来研究一下之前程序的问题: Node是一个单独的类,那么这样的类是可以被用户直接使用的,但是这个类由用户直接去使用,没有任何的意义,即: 这个类有用,但是不能让用户去用,只能让Link类去使用,内部类完成。 classLink{ // 用户唯一关注的是此类 // 使用内部类的最大好处是可以和外部类进行私有操作的互相访问 privateclassNode{ // 处理节点关系 privateStringdata; // 要保存的数据 privateNodenext; // 下一个节点 publicNode(Stringdata){ this.data=data; } publicvoidaddNode(NodenewNode){ // 增加节点 if(this.next==null){ // 当前节点之后没有节点 this.next=newNode; // 保存新节点 }else{ // 当前节点之后有节点了 this.next.addNode(newNode); // 向下继续判断 } } } privateNoderoot; // 根节点,第一个保存元素 publicbooleanadd(Stringdata){ // 增加数据 if(data==null){ // 如果保存的是一个空数据 returnfalse; // 增加失败 } // 将数据封装为节点,目的: 节点有next可以处理关系 NodenewNode=newNode(data); // 链表的关键就在于根节点 if(this.root==null){ // 现在没有根节点 this.root=newNode; // 第一个作为根节点 }else{ // 根节点有了,新的节点要保留在合适的位置 this.root.addNode(newNode); //Node类负责处理 } returntrue; // 增加成功 } } 使用内部类可以发现比之前的代码要节省一些,而且访问也方便了。 3.1.3 .2、增加多个数据: publicbooleanaddAll(数据 对象 []) 以上的操作是每次增加了一个对象,那么如果现在要求增加多个对象呢,例如: 增加对象数组。 可以采用循环数组的方式,每次调用add()方法。 publicbooleanaddAll(Stringdata[]){ // 一组数据 for(intx=0;x if(! this.add(data[x])){ // 保存不成功 returnfalse; } } returntrue; } 3.1.3 .3、统计数据个数: public intsize() 在一个链表之中,会保存多个数据(每一个数据都被封装为Node类对象),那么要想取得这些保存元素的个数,可以增加一个size()方法完成。 应该在Link类之中增加一个统计的属性: count: privateintcount;// 统计个数 当用户每一次调用add()方法增加新数据的时候应该做出统计: publicbooleanadd(Stringdata){ // 增加数据 if(data==null){ // 如果保存的是一个空数据 returnfalse; // 增加失败 } // 将数据封装为节点,目的: 节点有next可以处理关系 NodenewNode=newNode(data); // 链表的关键就在于根节点 if(this.root==null){ // 现在没有根节点 this.root=newNode; // 第一个作为根节点 }else{ // 根节点有了,新的节点要保留在合适的位置 this.root.addNode(newNode); //Node类负责处理 } this.count++; // 保存数据量增加 returntrue; // 增加成功 } 而在size()方法就是简单的将count这个变量的内容返回: publicintsize(){ returnthis.count; } 3.1.3 .4、判断是否是空链表: public booleanisEmpty() 所谓的空链表指的是链表之中不保存任何的数据,实际上这个null可以通过两种方式判断: 一种判断链表的根节点是否为null,另外一个是判断保存元素的个数是否为0。 publicbooleanisEmpty(){ returnthis.count==0; } 3.1.3 .5、查找数据是否存在: publicbooleancontains(数据 对象) 现在如果要想查询某个数据是否存在,那么基本的操作原理: 逐个盘查,盘查的具体实现还是应该交给Node类去处理,但是在盘查之前必须有一个前提: 有数据存在。 在Link类之中,增加查询的操作: publicbooleancontains(Stringdata){ // 查找数据 // 根节点没有数据,查找的也没有数据 if(this.root==null||data==null){ returnfalse; // 不需要进行查找了 } return this.root.containsNode(data) ; // 交给Node类处理 } 在Node类之中,完成具体的查询,查询的流程: · 判断当前节点的内容是否满足于查询内容,如果满足返回true; · 如果当前节点的内容不满足,则向后继续查,如果已经没有后续节点了,则返回false。 publicbooleancontainsNode(Stringdata){ // 查找数据 if(data.equals(this.data)){ // 与当前节点数据吻合 returntrue; }else{ // 与当前节点数据不吻合
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第五天 面向对象3 五天 面向 对象
![提示](https://static.bdocx.com/images/bang_tan.gif)