package com.bruce.homework0226;
import com.bruce.utils.MyException;
import java.io.Serializable;
import java.util.Arrays;
/**
* 实现LinkedList的基本功能
* Created by Bruce.Jiao on 2017/2/25.
*/
public class LinkedListV00<E> implements Serializable {
/**
* 双向链表中节点实例的个数
*/
private transient int size = 0;
/**
* 头节点
*/
private transient Node<E> head;
/**
* 尾节点
*/
private transient Node<E> last;
/**
* 空构造
*/
public LinkedListV00(){
head = new Node<E>(null, null, null);
}
/**
* 添加一个节点
* @param element
* @return
*/
public boolean add(E element){
linkNext(element);
return true;
}
/**
* 拿到制定位置的元素
* @param index
* @return
*/
public E get(int index) throws MyException{
if(index < 0 || index > size){
throw new MyException("索引越界");
}
return node(index).element;
}
/**
* 删除指定位置的元素
* 将index-1处节点的next指向index+1处节点,将index+1处节点的previous指向index-1节点
* @param index 节点位置
* @return 删除节点的element数据
*/
public E remove(int index) throws MyException{
if(index < 0 || index > size){
throw new MyException("节点索引越界");
}
return unlink(node(index));
}
/**
* 返回链表的长度
* @return 双向链表中节点实例的个数
*/
public int size(){
return size;
}
/**
* 拿到链表对应的数组
* @return 链表各节点的element元素组成的数组
*/
public Object[] toArray(){
Object[] array = new Object[size];
for(int i = 0;i<size;i++){
array[i] = node(i).element;
}
return array;
//源码
// Object[] result = new Object[size];
// int i = 0;
// for (Node<E> x = first; x != null; x = x.next)
// result[i++] = x.element;
// return result;
}
/**
* 表示一个节点的内部类
* @param <E> 链表元素泛型
*/
private static class Node<E>{
E element;
Node<E> prev;
Node<E> next;
Node(Node<E> prev,E element,Node<E> next){
this.element = element;
this.prev = prev;
this.next = next;
}
}
/**
* 根据索引拿对应的节点
* @param index 索引号
* @return 索引号对应的节点
*/
private Node<E> node(int index){
Node<E> x;
//如果index小于size的一半,即目标节点在链表前半部分
if(index < (size >> 1)){
//从第一个节点挨个向后查找,一直到(index-1)处,将其next赋值给x
x = head;
for(int i = 0; i<index;i++){
x = x.next;
}
}else{
//否则,即目标节点在链表后半部分,
//从最后一个节点挨个向前查找,一直查找到(index+1)处,将其previous赋值给x
x = last;
for(int i = size-1;i>index;i--){
x = x.prev;
}
}
//返回x
return x;
}
/**
* 链接下一个
* @param e 新节点的element
*/
private void linkNext(E e){
//将当前的last节点赋值给n
final Node<E> n = last;
//创建一个新的Node节点,其previous为n,next为null
final Node<E> newNode = new Node<E>(n,e,null);
//创建一个新的节点后,则last更新为新节点newNode
last = newNode;
//如果n为null,说明还是一个空的双向链表,将新节点newNode赋值给first
//否则,将newNode赋值给n的next
if(n == null){
head = newNode;//第一次添加的时候,将该元素放在头节点位置
}else{
n.next = newNode;
}
//添加一个新节点后,size加1
size++;
}
/**
* 从链表解除一个节点
* @param node 将要被链表接触关联的目标节点
* @return 目标节点的element元素
*/
private E unlink(Node<E> node){
//拿到传入节点的元素
final E element = node.element;
//拿到传入节点的next节点
final Node<E> next = node.next;
//拿到传入节点的previous节点
final Node<E> previous = node.prev;
//如果传入节点的previous=null,说明是第一个节点
if(previous == null){
//将链表第一个节点指向本节点的下一个节点next,即把原有的第一个节点解除
head = next;
}else{
//将本节点前一个节点的next指向本节点后一个节点,即跳过了本节点
previous.next = next;
//将本节点的previous节点设置为null
node.prev = null;
}
//如果传入节点的next=null,说明是最后一个节点
if(next == null){
//将链表最后一个节点指向本节点的前一个节点,即把原来的最后一个节点解除
last = previous;
}else{
//将本节点下一个节点的previous节点指向本节点的前一个节点,即跳过了本节点
next.prev = previous;
//本节点的next节点设置为null
node.next = null;
}
node.element = null;
size--;
return element;
}
/**
* 仅作为临时方法,打印链表元素使用,方面查看
* @return
*/
@Override
public String toString() {
return Arrays.toString(toArray());
}
}