Java实现自定义链表
来源:互联网 发布:数据结构书与算法java 编辑:程序博客网 时间:2024/06/18 13:34
与C语言比起来,Java实现链表不用考虑复杂的指针关系,一切皆对象,所以相对来说比较简单。
PS:以下代码均采用递归实现,不考虑效率,旨在理解结构。
1.入门级
首先实现一个节点类:
package jimo.love;public class Node { private String data;//数据 private Node next;//指向下一个节点 public Node(String data){ this.data = data; } public void setNext(Node next){ this.next = next; } public Node getNext(){ return this.next; } public String getData() { return data; } public void setData(String data) { this.data = data; }}
然后在主方法中生成节点,完成连接关系,并打印出来,看代码有解释:
package jimo.love;public class Test { public static void main(String[] args) { //1.准备所有数据 Node head = new Node("头节点"); Node n1 = new Node("n1"); Node n2 = new Node("n2"); head.setNext(n1); n1.setNext(n2); //2.取出所有数据 //方法一: Node curNode = head; while(curNode!=null){ System.out.println(curNode.getData()); curNode = curNode.getNext(); } //方法二,递归方式: print(head); } //采用递归方式 public static void print(Node curNode){ if(curNode==null){ return ; } System.out.println(curNode.getData()); print(curNode.getNext()); }}
代码中用了两种方式取数据,看执行结果:
可以看到Main方法里写的东西太多了,还要设置数据,输出数据。
但面向对象的思想让我们不需要关注太多的东西和具体的实现。
所以我们需要一个工具类,我们只关注存数据和取数据,并不关心怎么存,怎么取。
2.中级
我们增加一个Link类用于业务操作:
public class Link { private Node head; public void add(String data){ Node newNode = new Node(data); if(this.head==null){ this.head = newNode;//头节点 }else{ //头插法// newNode.setNext(this.head.getNext());// this.head.setNext(newNode); //尾插法 this.head.addNode(newNode); } } public void print(){ if(this.head!=null){ this.head.printNode(); } }}
其中的addNode和printNode方法来自Node类:
//递归添加节点 public void addNode(Node node){ if(this.next==null){ this.next = node; }else{ this.next.addNode(node); } } //递归打印节点 public void printNode(){ System.out.println(this.data); if(this.next!=null){ this.next.printNode(); } }
在主函数里:
Link link = new Link(); link.add("1"); link.add("2"); link.add("3"); link.print();
3.高级
在可用链表中,你不可能直接操作节点类吧,像这样:
Node n = new Node("n");
所以,我们要让Node类只能被Link类使用,具体方法是将Node类声明为Link类的私有内部类:
4.终极
一个链表不可能只有一个add方法吧,接下来就完善方法:
1.size():取得元素个数
在Link类中声明属性count:
private int count = 0;
在add函数里自加:
this.count++;//增加完就++
返回size:
//取得数量 public int size(){ return this.count; }
测试:
Link link = new Link(); link.add("1"); link.add("2"); link.add("3"); link.add(null); System.out.println(link.size());
可以看到我添加了一个null元素,但也添加进去了,添不添加取决于自己,我这里不让添加,所以在add函数里修改:
if(null==data){ return ; }
2.isEmpty():判断链表是否为空:
public boolean isEmpty(){ return 0==this.count; }
3.contains(data):判断数据是否存在:
在Link类中:
//根据内容查询数据 public boolean contains(String data){ if(null==data||null==this.head){ return false; }else{ return this.head.containNode(data); } }
在Node类中:
public boolean containNode(String data){ if(data.equals(this.data)){ return true; }else{ if(null!=this.next){ return this.next.containNode(data); }else{ return false;//递归结束条件 } } }
4.get(int index):根据索引查找数据:
在Link类添加属性:
private int index = 0;
在Node类添加方法:
public String getNode(int index){ //注意Link.this.index if(Link.this.index++==index){ return this.data; }else{ return this.next.getNode(index); } }
注意:Link.this.index是内部类获得外部类属性的方法。
在Link类添加方法:
//通过索引查找内容 public String get(int index){ if(index >= this.count){ return null; } this.index = 0;//每次从头向后查询 return this.head.getNode(index); }
注意:查找时索引从0开始,当然可以改成从1开始。
5.set(int index,data):根据索引修改内容:
其实和查找一样,只是操作不同方而已:
在Node类:
public void setNode(int index,String data){ if(Link.this.index++==index){ this.data = data; }else{ this.next.setNode(index, data); } }
在Link类:
//根据索引修改内容 public void set(int index,String data){ if(index >= this.count){ return ; }else{ this.head.setNode(index,data); } }
6.remove(data):删除一个元素:
这也是相对来说最复杂的部分,不过也很简单。
在Node类:
//对非根节点的删除 public void removeNode(Node preNode,String data){ if(data.equals(this.data)){ preNode.next = this.next; }else{ this.next.removeNode(this, data); } }
在Link类,要判断是否是根节点:
//删除 public void remove(String data){ if(this.contains(data)){ //删除根节点 if(data.equals(this.head.data)){ this.head = this.head.next; }else{ //非根节点 this.head.next.removeNode(this.head, data); } this.count--;//别忘了 } }
7.toArray():转化成数组:
在Link类添加一个属性:private String[] retArray;
在Node类:
public void toArrayNode(){ Link.this.retArray[Link.this.index++] = this.data; if(null!=this.next){ this.next.toArrayNode(); } }
在Link类:
public String[] toArray(){ if(null == this.head){ return null; } this.index = 0; this.retArray = new String[this.count]; this.head.toArrayNode(); return this.retArray; }
5.总结
以上代码不能够用于实战开发,只是为了理解引用关系的传递,后续的改进可以添加更多的方法,不用递归,加入泛型,做出和List一样的效果。
- Java实现自定义链表
- Java实现自定义链表
- java自定义栈(链表实现)
- Java自定义实现链栈
- Java自定义实现链队列
- 在java实现自定义链表(单向链表)
- 基于链表实现Java 自定义Stack栈
- 基于链表实现Java 自定义Queue队列
- 用java实现的自定义单向链表
- java 自定义单向链表实现“反序”输出
- Java小程序之自定义链表的实现
- java实现自定义标签
- Java实现自定义栈
- Java实现自定义序列
- Java自定义链表
- java自定义栈(数组实现)
- java中实现自定义注解
- 【Java】Treeset实现自定义排序
- 2015阿里移动推荐算法大赛总结
- 通过 Autostereograms 案例学习 OpenGL 和 OpenCL 的互操作性 英文原文:OpenGL / OpenCL Interoperability : A Case Study U
- SQL语句的MINUS,INTERSECT和UNION ALL
- jQuery转换JS原生代码
- Android中的cursor
- Java实现自定义链表
- 修改分库中的数据记录
- 2440挂载nfs
- 套接字
- js获取url协议、接口等信息
- 解决react-native fetch请求报错JSON parse error
- android 当状态栏背景色为白色时候 字体颜色的适应
- Json转java对象
- 人工智能概述