java双链表实现_java双链表实现

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());

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值