package day1501_手写双向链表;
// 链表类
public class SXLianBiao<T> {
private Node first; // 头部节点, 初始 null
private Node last; // 尾部节点, 初始 null
private int size; // 节点数量,初始值 0
public void add(T value) {
Node n = new Node();
n.value = value; // 数据封装到 n
if (size == 0) { // 添加第一个node 对象
n.prev = n; // n向前引用n
n.next = n; // n向后引用n
this.first = n; // n 是头部节点
this.last = n; // n 也是尾部节点
}else {
n.prev = this.last;
n.next = this.first;
this.last.next = n;
this.first.prev = n;
this.last = n;
}
this.size++;
}
public T get(int index) {
Node n = getNode(index);
return n.value;
}
private SXLianBiao<T>.Node getNode(int index) {
// i越界
// 取头尾
// 取中间
if (index < 0 || index >= this.size) {
throw new IndexOutOfBoundsException(""+index+"越界");
}
if (index == 0) {
return this.first;
}else if (index == this.size-1) {
return this.last;
}
Node n = null;
if (index < this.size/2) { // 前边一半
// n 引用first
n = this.first;
// 从 j 到 index
for (int j = 1; j < index; j++) {
n = n.next;
}
return n;
}else { // 后面一半
n = this.last;
for (int j = this.size-2; j >= index ; j--) {
n = n.prev;
}
}
return n;
}
public int size() {
return size;
}
// 内部类, 封装节点数据
// 节点类,辅助外部双向链表对象
// 来封装局部数据
private class Node{
T value; // 节点中封装的数据
Node prev; // 引用前一个节点对象
Node next; // 引用后一个节点对象
}
}