- 环形链表:
- 建议先不要看我写得自己先实现下,只将Node内部类复制自己命名得容器内,
实现方法:
a. add方法(添加到头部,尾部添加,指定位置添加)
b. get方法(获取首部,获取尾部,获取指定位置)
c. remove方法(删除首部,删除尾部,删除指定位置)
d. size方法(手动维护一个size变量,实现0(1)复杂度 )
e. 迭代器(实现迭代器,能够循环遍历)
手动实现之后(每个功能只实现一种也可以),再回头参照,思考下即可!
java
package com.nami.algorithm.study.day05;
import java.io.Serializable;
import java.util.Iterator;
import java.util.function.Consumer;
/**
* 环形双向哨兵链表
* 非线程安全
* beyond u self and trust u self.
*
* @Author: lbc
* @Date: 2023-09-01 9:07
* @email: 594599620@qq.com
* @Description: keep coding
*/
public class RingLinkedList<E> implements Serializable, Iterable<E>, Cloneable {
/**
* 容器已添加的元素
*/
private int size = 1;
/**
* 哨兵节点
*/
private Node sentinel = new Node(null, "-1", null);
/**
* 初始化哨兵
*/
public RingLinkedList() {
this.sentinel.prev = this.sentinel;
this.sentinel.next = this.sentinel;
}
/**
* 向链表添加数据
*
* @param element 添加的元素
*/
public void addFirst(E element) {
Node first = this.sentinel;
Node next = first.next;
Node node = new Node<>(first, element, next);
first.next = node;
next.prev = node;
++this.size;
}
/**
* 向链表尾部添加数据
*
* @param element
*/
public void addLast(E element) {
Node last = this.sentinel.prev;
Node node = new Node<>(last, element, sentinel);
last.next = node;
sentinel.prev = node;
++this.size;
}
/**
* 获取容器指定位置的值
*
* @param index
* @return
*/
public E get(int index) {
if (index > size - 1) {
throw new IndexOutOfBoundsException("元素不存在");
}
Node next = sentinel.next;
for (int i = 0; i < index; next = next.next, i++) {
}
if (sentinel == next) {
throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
}
return (E) next.value;
}
/**
* 获取指定位置节点node
*
* @param index
* @return
*/
private Node getNode(int index) {
Node next = sentinel.next;
for (int i = 0; i < index; next = next.next, i++) {
}
return next;
}
/**
* 向元素指定节点添加值
*
* @param index
* @param e
*/
public void add(int index, E e) {
if (index > size - 1) {
throw new IndexOutOfBoundsException("元素不存在");
}
Node node = getNode(index);
Node prev = node.prev;
Node node1 = new Node(prev, e, node);
node.prev = node1;
prev.next = node1;
++this.size;
}
/**
* 移除容器内第一个元素
*/
public void removeFirst() {
Node node = getNode(0);
if (sentinel == node) {
throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));
}
Node prev = node.prev;
Node next = node.next;
prev.next = next;
next.prev = prev;
--this.size;
}
/**
* 删除第一个元素
*/
public void removeFirst0() {
Node removed = this.sentinel.next;
if (removed == this.sentinel) {
throw new IndexOutOfBoundsException("容器内已无元素");
}
Node next = removed.next;
this.sentinel.next = next;
next.prev = this.sentinel;
}
/**
* 移除容器内指定位置元素
*
* @param index
*/
public void remove(int index) {
if (index > size - 1) {
throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
}
Node node = getNode(index);
if (sentinel == node) {
throw new IndexOutOfBoundsException(String.format("index [%d] 不合法%n", 0));
}
Node prev = node.prev;
Node next = node.next;
prev.next = next;
next.prev = prev;
--this.size;
}
/**
* 删除最后一个节点
*/
public void removeLast() {
Node prev = this.sentinel.prev;
if (prev == this.sentinel) {
return;
}
Node next = prev.next;
Node prev0 = prev.prev;
prev0.next = next;
next.prev = prev0;
--this.size;
}
/**
* 获取容器大小
*
* @return
*/
public int size() {
return this.size - 1;
}
/**
* 迭代器遍历
*
* @return
*/
@Override
public Iterator iterator() {
return new NodeIterator();
}
/**
* 匿名内部类
* 内部类使用到了外部类的成员变量时,不能使用static修饰
*/
private class NodeIterator implements Iterator {
Node node = sentinel.next;
@Override
public boolean hasNext() {
return node != sentinel;
}
@Override
public Object next() {
Object value = node.value;
node = node.next;
return value;
}
}
/**
* while实现
*
* @param consumer
*/
public void forEach(Consumer consumer) {
Node firstNode = this.sentinel.next;
while (firstNode != sentinel) {
consumer.accept(firstNode.value);
firstNode = firstNode.next;
}
}
/**
* Node类型 节点对象
* 二者为组合关系,所以 由外部类变为内部类,对外隐藏实现细节
*/
private static class Node<E> {
/**
* 上一个节点
*/
private Node<E> prev;
/**
* 值
*/
private E value;
/**
* 下一个节点
*/
private Node<E> next;
public Node(Node<E> prev, E value, Node<E> next) {
this.prev = prev;
this.value = value;
this.next = next;
}
}
}