双向链表:
在单链表中的结点仅仅包含指向其后继结点的指针,所以要查找一个指定结点的后继结点,只要顺着它的后继指针即可一次找到,其时间复杂度是O(1) ,但若要查找一个指定结点的前驱结点,则要从单链表的表头开始顺着链一次查找,其时间复杂度是O(n),这是快速进行链表操作的一大障碍。为克服单向链表这一单向性缺点,可对单链表进行重新定义,使其结点具有两个指针域,一个指针指向前驱结点,另一个指针指向后继结点,这种类型的链表称为双向链表:
双向链表的结点类描述如下:
package com.test1;
public class DulNode
{
private Object data; // 存放结点值的数据域
private DulNode prior; //存放指向前驱结点的指针域
private DulNode next; //存放指向后继结点的指针域
public DulNode() //无参数构造函数
{
}
//构造数据域值为data的新结点
public DulNode(Object data)
{
this.data=data;
this.prior=null;
this.next=next;
}
public Object getData()
{
return data;
}
public void setData(Object data)
{
this.data=data;
}
public DulNode getPrior()
{
return prior;
}
public void setPrior(DulNode prior)
{
this.prior=prior;
}
public DulNode getNext()
{
return next;
}
public void setNext(DulNode next)
{
this.next=next;
}
}
双向链表也与单链表一样,只要首尾相连即可构成双向循环链表。在双向循环链表中存在两个环,它们分别由前驱指针和后断指针连接而成。
双向循环链表类的具体描述如下:
package com.test1;
import java.util.Scanner;
public class DulLinkList implements List
{
private DulNode head; //双向链表的头结点
//双向链表的构造函数
public DulLinkList()
{
head=new DulNode();//初始化头结点
head.setPrior(head); //初始化头结点的前驱和后继
head.setNext(head);
}
//从从表尾到表头逆向创建双向循环链表的算法,其中n尾该双向循环链表的结点个数
public DulLinkList(int n) throws Exception
{
this();
Scanner sc=new Scanner(System.in); //构造用于输入的对象
for(int j=0;j<n;j++)
{
insert(0, sc.next()); //生成新结点,插入到表头
}
}
@Override
public void clear()
{
// TODO Auto-generated method stub
}
@Override
public boolean isEmpty()
{
// TODO Auto-generated method stub
return false;
}
@Override
public int length()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public Object get(int i) throws Exception
{
// TODO Auto-generated method stub
return null;
}
@Override
public void insert(int i, Object x) throws Exception
{
// TODO Auto-generated method stub
DulNode p=head.getNext(); //初始化,p指向首结点
int j=0; //计数器
while(! p.equals(head) && j<i) //寻找插入位置i
{
p=p.getNext();//指向后继结点
++j;
}
if(j != i && !p.equals(head))
{
throw new Exception("i不合法");
}
DulNode s=new DulNode();//生成新结点
p.getPrior().setNext(s);
s.setPrior(p.getPrior());
s.setNext(p);
p.setPrior(s);
}
@Override
public void remove(int i) throws Exception
{
// TODO Auto-generated method stub
DulNode p=head.getNext();//初始化,p指向首结点
int j=0; //j 为计数器
while(!p.equals(head) && j<i) //寻找删除位置
{
p =p.getNext();
++j;
}
if(j != i)
{
throw new Exception("删除位置不合理");
}
p.getPrior().setNext(p.getNext());
p.getNext().setPrior(p.getPrior());
}
@Override
public int indexOf(Object x)
{
// TODO Auto-generated method stub
return 0;
}
@Override
public void display()
{
// TODO Auto-generated method stub
DulNode node=head.getNext();//取出首结点
while(!node.equals(head))
{
System.out.println(node.getData()+""); //取出结点的数值域
node=node.getNext();//取下一个结点
}
System.out.println(); //换行
}
public DulNode getHead()
{
return head;
}
public void setHead(DulNode head)
{
this.head=head;
}
}