package org.com.data_structure.list.demo;
import java.util.List;
/**
* 双链表的实现
* @author nmw
*
*/
public final class DoubleLinked {
/**
* 头节点
*/
private transient Node head = new Node(null,null,null);
/**
* 表示可以在当前的位置插入元素 表示链表的大小.
*/
private transient int size = 0;
/**
* 构造不含元素的链表
*/
public DoubleLinked(){
head.next = head.previous = head;
}
/**
* 根据给定的链表构造新的链表/
* @param d
*/
public DoubleLinked(DoubleLinked d){
this();
this.addAll(d);
}
/**
* 链表的大小.
* @return
*/
public int size(){
return size;
}
/**
* 链表是否为空.
* @return true or false
*/
public boolean isEmpty(){
return size==0;
}
/**
* 是否包含给定的元素
* @param obj
* @return true or false
*/
public boolean containts(Object obj){
return this.indexOf(obj) != -1;
}
/**
* 移除链表的第一个元素 若链表为空则返回 null
* @return 返回被删除的元素
*/
public Object remove(){
Object obj = null;
if(this.size == 0)
return null;
Node p = head.next; //获得第一个元素
p.next.previous = head; //重构链表
head.next = p.next;
this.size -- ; //链表大小-1
obj = p.obj;
return obj;
}
/**
* 移除链表中最后一个元素 若链表为空则抛出返回null
* @return 返回最后一个元素
*/
public Object removeLast(){
Object obj = null;
if(this.size == 0)
return null;
Node p = this.head.previous; //获得最后一个节点
//重构链表
p.previous.next = head; //p的上一个元素的下一个元素指向head
head.previous = p.previous; //head的上一个元素 指向 p的上一个元素/
this.size--;
obj = p.obj;
return obj;
}
/**
* 移除指定索引处的元素 若 index <0或index>size 则泡异常
* 元素下标从0开始
* @param index
* @return 返回指定索引处的元素/
*/
public Object remove(int index)throws IndexOutOfBoundsException{
this.check(index); //检查给定的index是否合理
Node node = this.getNode(index);
Node p = node.previous; //当前元素的上一个元素
Node n = p.next; //当前元素的下一个元素
p.next = n;
n.previous = p;
this.size--;
return node.obj;
}
/**
* 移除链表中第一次出现时的指定元素
* @param obj
* @return 若存在则返回true 否则返回false.
*/
public boolean remove(Object obj){
if(this.size == 0)
return false;
int i = 0;
Node node = this.head;
boolean fog = false;
int size = this.size;
if(obj == null)
while(i
node = node.next;
if(node.obj == null){
fog = true;
break; //表示找到该节点
}
i++;
}
else{
while(i
node = node.next;
if(obj.equals(node.obj)){
fog = true;
break;//表示找到该节点
}
i++;
}
}
//重构链表
if(fog){
Node p = node.previous;
Node n = node.next;
p.next = n;
n.previous = p;
}
return fog;
}
/**
* 删除元素最后一次出现的节点
* @param o
* @return
*/
public boolean removeLastOccurrence(Object obj){
if(this.size == 0)
return false;
boolean fog = false;
int i = 0;
int s = this.size;
Node node = this.head;
Node lastNode = null; //最后出现的节点
if(obj == null){
while(i
node = node.next;
if(node.obj == null){
lastNode = node;
fog = true; //找出最后出现的节点
}
i++;
}
}
else{
while(i
node = node.next;
if(obj.equals(node.obj)){
lastNode = node;
fog = true;
}
i++;
}
}
//重构链表
if(fog){
Node p = lastNode.previous;
Node n = lastNode.next;
p.next = n;
n.previous = p;
}
return fog;
}
/**
* 检查给定值是否越界
* @param index
* @throws IndexOutOfBoundsException
*/
private void check(int index)throws IndexOutOfBoundsException{
if(index<0 || index>=this.size)
throw new IndexOutOfBoundsException("输入的值不合理:"+index);
}
/**
* 将元素追加到链表的尾部/
* @param obj
* @return
*/
public boolean add(Object obj){
Node node = this.createNode(obj);
Node p = this.head.previous; //找出最后一个元素
node.previous = p; //设置新加元素的上一个元素
node.next = head; //设置新增元素的下一个元素
p.next = node; //设置增加前最后一个元素的下一个元素/
this.head.previous = node;
this.size++; //链表大小+1
return true;
}
/**
* 将指定元素追加到指定位置
* @param index
* @param obj
* @return
*/
public void add(int index,Object obj){
this.check(index);
Node node = this.createNode(obj); //创建新的节点
Node indexNode = this.getNode(index); //获得当前索引处的节点
Node p = indexNode.previous; //当前索引的上一个节点
node.previous = p; //新节点的上一个元素
node.next = indexNode; //新节点的下一个元素
p.next = node; //当前节点的下一个节点指向new Node
indexNode.previous = node; //当前节点的上一个元素指向 new Node
this.size++;
}
/**
* 在第一个节点处新增一个节点
* @param obj
* @return true
*/
public boolean addFirst(Object obj){
Node newNode = this.createNode(obj); //创建新的 节点
Node n = head.next;
newNode.next = n;
newNode.previous = head;
head.next = newNode;
this.size++;
return true;
}
/**
* 获得第一个元素
* @return
*/
public Object getFirst(){
if(this.size == 0){
return null;
}
return this.head.next.obj;
}
/**
* 获得最后一个元素, 若链表为空 则返回null 否则返回最后一个节点的值
* @return
*/
public Object getLast(){
if(this.size == 0){
return null;
}
return this.head.previous.obj;
}
/**
* 返回指定索引处的节点值 下标从0开始
* @param index
* @return
*/
public Object get(int index){
this.check(index);
Object obj = null;
Node node = this.getNode(index);
obj = node.obj;
return obj;
}
/**
* 索引从0开始
* @param obj
* @return 返回给定元素在链表中索引 若无 则返回null
*/
public int indexOf(Object obj){
int i=0;
Node node = this.head;
int s = this.size;
if(obj == null){
while(i
node = node.next;
if(node == null)
return i;
i++;
}
}else{
while(i
node = node.next;
if(obj.equals(node.obj))
return i;
i++;
}
}
return -1;
}
/**
* 将链表清空
*/
public void clear(){
this.head.next = this.head.previous = null;
this.size = 0;
}
/**
* 替换指定索引处的节点
* @param index
* @param obj
* @return
*/
public Object set(int index,Object obj){
this.check(index);
Node node = this.getNode(index); //获得指定索引处的节点
Object o = node.obj; //获得节点值
node.obj = obj; //替换节点值
return o;
}
/**
* 返回该元素最后一次出现的索引值
* 若包含该元素 则返回下标 负责 返回-1
* @param obj
* @return
*/
public int lastIndexOf(Object obj){
int index = -1;
int i = 0;
int s = this.size;
Node node = this.head;
if(obj == null){
while(i < s){
node = node.next;
if(node.obj == null){
index = i;
}
i++;
}
}
else{
while(i < s){
node = node.next;
if(obj.equals(node.obj)){
index = i;
}
i++;
}
}
return index;
}
/**
* 返回该链表的 数组表示
* @return
*/
public Object[] toArray(){
int objLength = this.size;
Object[] obj = new Object[objLength];
Node node = this.head;
int i=0;
while(i
node = node.next;
obj[i++] = node.obj;
}
return obj;
}
/**
* 将指定的链表最追加到 当前链表中
* @param d
* @return
*/
public boolean addAll(DoubleLinked d){
if(d == null)
throw new NullPointerException("链表不能为空+"+d);
Node tlast = this.head.previous; //当前节点的上一个节点
Node dfirst = d.head.next; //指定链表的第一个节点
Node dLast = d.head.previous; //指定节点的最后一个节点
tlast.next = dfirst; //将链表的最后一个节点指向 给定链表的第一个节点
dfirst.previous = tlast; //指定链表的第一元素的上一个节点指向链表的最后一个节点
dLast.next = this.head;
this.head.previous = dLast;
this.size = this.size + d.size; //新链表的长度
return true;
}
/**
* 构造一个节点
* @param obj
* @return Node
*/
private Node createNode(Object obj){
return new Node(obj,null,null);
}
private Node getNode(int index){
check(index);
Node node = this.head;
int fog = this.size - index;
int i=0;
if(fog<=index){
while(i
node = node.next;
i++;
}
}
else{
while(i
node = node.previous;
i++;
}
}
return node;
}
/**
* 节点元素
* @author nmw
*
*/
private static class Node{
Node next; //节点的下一个元素
Object obj ; //节点值
Node previous ; //节点上一个原元素
public Node(Object obj,Node next,Node previous){
this.obj = obj;
this.next = next;
this.previous = previous;
}
}
/**
* 比较两个链表是否相等 若链表的每一个元素都相等 则 返回true
*/
@Override
public boolean equals(Object obj) {
if(obj == this)
return true;
else if(obj instanceof DoubleLinked){
int i=0;
Node n = this.head;
DoubleLinked d = (DoubleLinked)obj;
Node o = d.head;
if(this.size != d.size )
return false;
while(i
n = n.next;
o = o.next;
if(n.obj == null){
if(o.obj != null)
return false;
}
else{
if(!n.obj.equals(o.obj)){
return false;
}
}
}
return true;
}
return false;
}
/**
* 返回链表的字符串表示
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer("[ ");
Node node = this.head;
int i=0;
while(i
node = node.next;
s.append(node.obj);
i++;
if(i != this.size){
s.append(",");
}
}
s.append(" ]");
return s.toString();
}
public static void main(String[] args){
DoubleLinked d = new DoubleLinked();
for(int i=0;i<10;i++){
d.add(i);
}
DoubleLinked dl = new DoubleLinked(d);
System.out.println(dl.toString());
}
}