package com.coding.basic;
import java.util.NoSuchElementException;
/**
* 链表数据结构
* LinkedList
* @author greenhills
* 2017年2月22日 下午11:52:41
*/
public class LinkedList implements List {
/**
* 链表数据量
*/
private int size=0;
/**
* 链表头节点
*/
private Node head;
/**
* 链表尾节点
*/
private Node tail;
/**
* 在数据链尾部添加数据
*/
@Override
public void add(Object o) {
addLast(o);
}
/**
* 在数据链指定位置添加数据
*/
@Override
public void add(int index, Object data) {
checkIndex(index);
Node old=getNode(index);
link2Before(old,data);
}
/**
* 获取指定索引处数据
*/
@Override
public Object get(int index) {
checkIndex(index);
return getNode(index).data;
}
/**
* 移除指定索引位置的节点
*/
@Override
public Object remove(int index) {
checkIndex(index);
return unlink(getNode(index));
}
/**
* 获取数据链的数据量
*/
@Override
public int size() {
return this.size;
}
/**
* 获取数据链的数据量
*/
@Override
@Deprecated
public int capacity() {
return size();
}
/**
* 判断是否为空
*/
@Override
public boolean isEmpty() {
return this.size==0;
}
/**
* 在数据链头部追加数据
* @param data
*/
public void addFirst(Object data){
final Node oldNode=this.head;
final Node newNode=new Node(null,data,oldNode);//形成新节点,并指向第一个节点
this.head = newNode; //变更集合保存的首节点
if(oldNode == null){ //没有数据
this.tail = newNode; //变更集合保存的尾节点
}else{
oldNode.prev = newNode; //原首节点指向新的首节点
}
this.size++;//数据量加1
}
/**
* 在数据链尾部追加数据
* @param data
*/
public void addLast(Object data){
final Node oldNode=this.tail;
final Node newNode=new Node(oldNode,data,null);//形成新节点,并指向最后一个节点
this.tail = newNode; //变更集合保存的尾节点
if(oldNode == null){ //没有数据
this.head = newNode; //变更集合保存的首节点
}else{
oldNode.next = newNode;//原尾节点指向新的尾节点
}
this.size++;//数据量加1
}
/**
* 把指定数据链接到指定节点前面
*/
void link2Before(Node node,Object data){
//传进来的node就是后节点
final Node prev=node.prev; //指定节点的上一个节点(前节点)
//生成新节点,并指向前后的节点
final Node newNode=new Node(prev,data,node);//生成新节点
//后节点指向新节点
node.prev = newNode;
//前节点指向新节点
if(prev == null){//没有前节点了(当前节点已是首节点)
this.head = newNode;//把新的节点作为首节点
}else{
prev.next = newNode;
}
this.size++;//数据量加1
}
/**
* 把指定数据链接到指定节点后面
*/
void link2Last(Node node,Object data){
//传进来的node就是前节点
final Node next=node.next; //指定节点的下一个节点(后节点)
//生成新节点,并指向前后的节点
final Node newNode=new Node(node,data,next);
//前节点指向新节点
node.next = newNode;
//后节点指向新节点
if(next == null){//没有后节点了(当前节点已是尾节点)
this.tail = newNode;//把新的节点作为尾节点
}else{
next.prev = newNode;
}
this.size++;//数据量加1
}
/**
* 移除首节点
* @return
*/
public Object removeFirst(){
return unlink(getNode(0));
}
/**
* 移除尾节点
* @return
*/
public Object removeLast(){
return unlink(getNode(this.size-1));
}
/**
* 移除节点
* @return
*/
Object unlink(Node node){
final Object element = node.data;
final Node next = node.next; //下一个节点
final Node prev = node.prev;//前一个节点
if (prev == null) {//待删除节点是首节点
head = next;
} else {
prev.next = next;
node.prev = null;//解除待删除节点的引用关系
}
if (next == null) {//待删除节点是尾节点
tail = prev;
} else {
next.prev = prev;
node.next = null;//解除待删除节点的引用关系
}
node.data = null;//清除节点数据
size--;
return element;//返回清除节点数据
}
/**
* 在中间位置创建Iterator遍历
* @return
*/
public Iterator iterator() {
return new Its(this.size>>1);
}
/**
* 在指定位置创建Iterator遍历
* @return
*/
public Iterator iterator(int index) {
checkIndex(index);
return new Its(index);
}
/**
* 获取指定索引的节点对象
* @param @param index
* @param @return
*/
private Node getNode(int index){
if (index < (this.size >> 1)) { //在前半部分
Node node = this.head;
for (int i = 0; i < index; i++){
node = node.next; //向后查找
}
return node;
} else { //在后半部分
Node node = this.tail;
for (int i = this.size - 1; i > index; i--){
node = node.prev; //向前查找
}
return node;
}
}
/**
* 判断是否为有效索引
* @param @param index
* @param @return
*/
private boolean isEffectiveIndex(int index){
return (index>=0 && index < size);
}
/**
* 检测索引有效性,无效时抛出异常
* @param index
*/
private void checkIndex(int index) {
if (!isEffectiveIndex(index))
throw new IndexOutOfBoundsException("Index: "+index+" Out Of Bounds, 最大索引: "+(size-1));
}
/**
* 实现Iterator的内部实现类
*/
private class Its implements Iterator {
private Node lastReturned = null;
private Node node;//当前节点
private int index;//当前节点索引
public Its(int index){
node = isEffectiveIndex(index) ? getNode(index) : null;
this.index = index;
}
@Override
public boolean hasNext() {
return index < size;
}
@Override
public Object next() {
if (!hasNext())
throw new NoSuchElementException();
lastReturned = node;
node = node.next;
index++;
return lastReturned.data;
}
public boolean hasPrevious() {
return index >= 0;
}
public Object previous() {
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = node;
node = node.prev;
index--;
return lastReturned.data;
}
}
/**
* 节点数据
* Node
*/
private static class Node{
Object data;
Node prev;
Node next;
Node(Node prev,Object data,Node next){
this.prev=prev;
this.data=data;
this.next=next;
}
}
}