JAVA中自带的的LinkedList, 是一个双向链表,而使用双向链表的好处就是操作速度相比于单向链表快捷,因此在手搓链表的时候我们也选择用双向链表尽可能的去模拟LinkedList同时理解链表。
一、效果展示
自己搓的:

官方的:

如图:能够实现基本的增删改查,且与官方的大致相同
二、 代码展示
MyLinkList 类
// 这是一个构造方法,用来创建一个空的链表
public MyLinkList() {
this.fist = null;
this.last = null;
}
// 这是一个方法,用来在链表的末尾添加一个元素
public boolean add(E e) {
if (fist == null) {
// 如果链表为空,就创建一个新的节点,把给定的元素作为数据,并把它赋值给first和last字段
Node<E> newnode = new Node<>(e, null, null);
last = newnode;
fist = newnode;
} else {
// 如果链表不为空,就创建一个新的节点,把给定的元素作为数据,并把它插入到last节点的后面
Node<E> newnode = new Node<>(e, last, null);
last.setNext(newnode);
last = newnode;
}
// 把链表的大小加一,并返回true表示添加成功
this.size++;
return true;
}
// 这是一个方法,用来在链表的指定位置插入一个元素
public void add(int index, E element) {
// 定义一个当前节点的引用,初始指向first节点
Node<E> current = fist;
if (index == size) {
// 如果索引等于链表的大小,就调用add方法在末尾添加元素
add(element);
} else if (index == 0) {
// 如果索引等于0,就创建一个新的节点,并把它插入到first节点的前面
Node<E> newnode = new Node<>(element, null, fist);
fist.setPrev(newnode);
fist = newnode;
} else {
// 如果索引在0和size之间,就遍历链表,找到对应位置的节点
int i = 0;
while (i++ != index) {
current = current.getNext();
}
// 创建一个新的节点,并把它插入到当前节点的前面和后面节点之间
Node<E> newnode = new Node<>(element, current.getPrev(), current);
current.getPrev().setNext(newnode);
current.setPrev(newnode);
}
}
// 这是一个方法,用来从链表中删除一个元素
public boolean remove(E e) {
// 定义一个计数器和当前节点的引用,初始指向first节点
int i = 0;
Node<E> current = fist;
while (i++ != size - 1) {
// 遍历链表,如果找到数据等于给定元素的节点,就删除它,并返回true表示删除成功
if (current.getData() == e) {
if (current.getPrev() != null) current.getPrev().setNext(current.getNext());
else {
System.out.println("报错");
}
return true;
}
// 否则继续遍历下一个节点
current = (current.getNext());
}
// 如果遍历完毕没有找到匹配的节点,就把first和last都设为null,并把size设为0,并返回false表示删除失败
fist = null;
last = null;
size--;
return false;
}
// 这是一个方法,用来从链表中删除指定位置的元素,并返回被删除的元素
public Object remove(int index) {
if (index == 0) {
// 如果索引等于0,就保存first节点,并把first节点设为它的下一个节点,并断开原来first节点的连接
Node<E> re = fist;
Node<E> node = fist.getNext();
fist.setNext(null);
node.setPrev(null);
fist = node;
// 把链表的大小减一,并返回被删除的元素
size--;
return re.getData();
} else {
// 如果索引不等于0,就找到对应位置的节点,并把它从链表中移除
Node<E> current = getN(index);
current.getPrev().setNext(current.getNext());
// 把链表的大小减一,并返回被删除的元素
size--;
return current.getData();
}
}
// 这是一个私有方法,用来根据索引获取链表中的节点
private Node<E> getN(int index) {
// 定义一个计数器和当前节点的引用,初始指向first节点
int i = 0;
Node<E> current = fist;
while (i++ != index) {
// 遍历链表,直到找到对应位置的节点
current = current.getNext();
}
// 返回该节点
return current;
}
// 这是一个方法,用来根据索引获取链表中的元素
public E get(int index) {
// 调用getN方法获取对应位置的节点,并返回它的数据
return getN(index).getData();
}
// 这是一个方法,用来获取链表中的第一个元素
public E getFirst() {
// 返回first节点的数据
return fist.getData();
}
// 这是一个方法,用来获取链表中的最后一个元素
public E getLast() {
// 返回last节点的数据
return last.getData();
}
// 这是一个方法,用来修改链表中指定位置的元素,并返回原来的元素
public E set(int index, E element) {
// 调用getN方法获取对应位置的节点,并保存它的数据
Node<E> current = getN(index);
E e = current.getData();
// 把给定的元素设为当前节点的数据,并返回原来的数据
current.setData(element);
return e;
}
// 这是一个方法,用来清空链表中的所有元素
public void clear() {
// 定义一个计数器,并从last节点开始遍历链表
int i = 0;
while (i++ != size - 1) {
// 保存last节点的前一个节点,并断开last节点的连接
Node<E> rem = last.getPrev();
last.setPrev(null);
last.setNext(null);
last = rem;
}
// 把last和first都设为null,并把size设为0
last = null;
fist = null;
size = 0;
}
// 这是一个方法,用来获取链表中元素的个数
public int size() {
// 返回size字段的值
return size;
}
@Override
// 这是一个重写的方法,用来把链表转换为字符串形式
public String toString() {
// 创建一个字符串连接器,用来拼接链表中的元素,使用逗号分隔,使用方括号包围
StringJoiner stringJoiner = new StringJoiner(", ", "[", "]");
// 定义一个当前节点的引用,初始指向first节点,并遍历链表
Node<E> current = fist;
for (int i = 0; i < size; i++) {
// 把当前节点的数据添加到字符串连接器中,并继续遍历下一个节点
stringJoiner.add((CharSequence) current.getData());
current = current.getNext();
}
// 返回字符串连接器生成的字符串
return stringJoiner.toString();
}
Node 类
public class Node<E> {
private Node<E> prev;
private Node<E> next;
private E data;
public Node(E data, Node<E> prev, Node<E> next) {
this.data = data;
this.prev = prev;
this.next = next;
}
public Node<E> getPrev() {
return prev;
}
public void setPrev(Node<E> prev) {
this.prev = prev;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
}
1542

被折叠的 条评论
为什么被折叠?



