1,若有不懂可网易云课堂李兴华老师的讲解
//单向链表的基本形式:主要有内部类,私有属性的访问。和对this关键字,引用传递的理解
class Produce {
public static void main(String[] args) {
Link link = new Link();
link.add("hello");
link.add("world");
link.add("lisi");
link.add("zhangsan");
System.out.println("0脚标::" + link.getIndex(0));
System.out.println("6脚标::" + link.getIndex(6));
System.out.println("原来::" + link.size());
link.remove("lisi");
System.out.println("后来::" + link.size());
// System.out.println(link.replace(1,"wo"));
System.out.println(link.contains("hello"));
System.out.println(link.contains("hllo"));
Object[] data = link.toArray();
for (Object info : data) {
System.out.println(info.toString());
}
}
}
// Link 类
class Link {
// 节点类
private class Node {
private Object data;// 要存储的数据
private Node next;// 下一个节点
public Node(Object data) {
this.data = data;
}
public void addNode(Node node) {
if (this.next == null) {
this.next = node;
} else {
this.next.addNode(node);// 当前节点的next节点继续添加
}
}
public boolean containNode(Object data) {
if (data.equals(this.data)) {
return true;
} else {
if (this.next != null)// 如果当前节点的next存在,继续判断
return this.next.containNode(data);
}
return false;
}
public Object getIndexNode(int index) {
if (Link.this.foot++ == index)// 如果当前脚标和index相等
return this.data;
return this.next.getIndexNode(index);
}
public void replaceNode(int index, Object data) {
if (Link.this.foot++ == index)// 如果当前脚标和index相等
this.data = data;
this.next.replaceNode(index, data);
}
// 传入要删除节点的上一个节点
// 第一次: Link.root 第二次:this 第三次:this.next
public void removeNode(Node pervious, Object data) {
if (data.equals(this.data)) {
pervious.next = this.next;
} else {
this.next.removeNode(this, data);
}
}
public void toArrayNode() {
Link.this.retArray[Link.this.foot++] = this.data;
if (this.next != null)
this.next.toArrayNode();
}
}
private Node root;// 根节点
private int count = 0;
private int foot = 0;
private Object[] retArray;
// 添加的方法
public void add(Object data) {
Node node = new Node(data);
if (this.root == null) {
this.root = node;
} else {
// 根节点不为null,此时我们交给Node类来处理
this.root.addNode(node);
}
this.count++;
}
// 获取链表元素的长度
public int size() {
return this.count;
}
// 判断链表的元素是否为空 1.size()==null? 2.root==?
public boolean isEmpty() {
return this.count == 0;
}
// 判断是否包含某个元素
public boolean contains(Object data) {
// 如果当前数据为null 或者 root节点不存在
if (this.root == null || data == null)
return false;
return this.root.containNode(data);
}
// 根据索引查询数据
public Object getIndex(int index) {
if (index > this.count)
return null;
this.foot = 0;// 修订脚标的值
return this.root.getIndexNode(index);
}
// 修改链表数据
public void replace(int index, Object data) {
if (index > this.count)
return;
this.foot = 0;// 修订脚标的值
this.root.replaceNode(index, data);
}
// 删除链表数据
/*
* 删除的原理 要删除节点的上一个节点的next。等于要删除节点的next。这样就空出当前节点 所以这就需要有两节点即当前的节点和当前节点的上一个节点
* 所以我们要分两种情况处理:1.只有根节点时,我们由Link类处理 2 其余由Node类处理
*/
public void remove(Object data) {
// 判断数据是否存在
if (this.contains(data)) {
// 判断要删除的数据是否是跟节点数据,
// data 是Node类的对象 此处直接访问内部类的私有对象
if (data.equals(this.root.data)) {
this.root = this.root.next;
} else {
this.root.next.removeNode(this.root, data);
}
}
this.count--;
}
// 对象数组转换
public Object[] toArray() {
if (this.root == null) {
return null;
} else {
//创建相同大小数组
this.retArray = new Object[this.count];
this.foot = 0;
this.root.toArrayNode();
}
return this.retArray;
}
}