本篇是恋上数据结构与算法(第一季)的学习笔记, 使用JAVA语言
一、单向循环链表
- 单向循环量链表, 就是尾节点的
next
, 指向头节点
1、插入方法
- 单向循环链表插入数据时, 有一点与单项链表不同, 那就是需要取出最后一个节点的
next
指向头结点
public void add(int index, E element) {
rangeCheckForAdd(index);
if (index == 0) {
// 创建新节点, 并指向原链表的first节点
Node<E> node = new Node<>(element, first);
// 取出最后一个节点
Node<E> last = size == 0 ? first : node(size - 1);
// 最后一个节点的next指向新节点
last.next = node;
// first指针指向新节点
first = node;
}else {
Node<E> prev = node(index - 1);
prev.next = new Node<>(element, prev.next);
}
size++;
}
2、删除节点
- 删除节点, 要保证尾节点指向头节点, 当只有一个节点时,
first
指向null
public E remove(int index) {
Node<E> node = first;
if (index == 0) {
if (size == 1) {
first = null;
}else {
Node<E> last = node(size - 1);
first = first.next;
last.next = first;
}
}else {
Node<E> prev = node(index - 1);
node = prev.next;
prev.next = node.next;
}
size--;
return node.element;
}
二、双向循环链表
- 双向循环链表, 首节点的
prev
指向尾节点, 尾节点的next
指向首节点
1、插入节点
- 插入节点后, 需要保证首节点的
prev
指向尾节点, 尾节点的next
指向首节点
public void add(int index, E element) {
rangeCheckForAdd(index);
// 如果 index == size, 说明添加的索引是最后位置
if (index == size) {
// 创建新节点, prev指向原链表的尾节点, next指向首节点
Node<E> node = new Node<>(last, element, first);
// 当原链表没有任何节点
if (size == 0) {
first = node;
last = node;
node.prev = node;
node.next = node;
}else {
// 原链表尾节点next指向node
last.next = node;
// 原链表头结点prev指向node
first.prev = node;
// last指向新的尾节点
last = node;
}
}else {
// 添加新节点后的下一个节点
Node<E> next = node(index);
// 添加新节点后的上一个节点
Node<E> prev = next.prev;
// 创建新节点, 新节点的上一个节点时prev, 新节点的下一个节点是next
Node<E> node = new Node<>(prev, element, next);
// next的上一个节点是新节点
next.prev = node;
// prev的下一个节点是新节点
prev.next = node;
// 当next == first时, 说明新添加节点的索引是0
if (next == first) {
first = node;
}
}
size++;
}
2、删除节点
- 删除节点, 就是在环上去掉某一个节点, 然后根据删除的节点是首节点或者尾节点来处理
first
和last
public E remove(int index) {
// 需要删除的节点
Node<E> node = node(index);
if (size == 1) {
first = null;
last = null;
}else {
// 删除节点的前一个节点
Node<E> prev = node.prev;
// 删除节点的后一个节点
Node<E> next = node.next;
next.prev = prev;
prev.next = next;
// 如果node == first, 说明删除的是第一个节点
if (node == first) {
first = next;
}
// 如果next == last, 说明删除的是最后一个节点
if (next == last) {
last = prev;
}
}
size--;
return node.element;
}