公用接口:

<span style="font-family:SimSun;font-size:18px;">package linearList;

import org.omg.CORBA.OBJ_ADAPTER;

public interface ILiist {
	public void clear();// 置空表

	public boolean isEmpty();// 是否为空

	public int length();// 数据元素个数

	public Object get(int i) throws Exception;// 返回第i个数据元素的值

	public void insert(int i, Object x) throws Exception;// 在第i个数据元素之前插入一个值为x的数据元素

	public void remove(int i) throws Exception;//删除并返回第i个元素
	
	public int indexOf(Object x);//返回首次出现指定的数据元素的位序号,
	                             //若线性表不包含此数据元素,则返回-1
	
	public void display();//输出
	
}
</span>

双向链表的结点类:

<span style="font-family:SimSun;font-size:18px;">package linearList;

public class DuLNode {
	public Object data;
	public DuLNode prior;//存放指向前驱结点的指针域
	public DuLNode next;//存放指向后继结点的指针域
	public DuLNode(){
		this(null);
	}
	public DuLNode(Object data){//构造数据域为data的新结点
		this.data=data;
		this.prior=null;
		this.next=null;
	}
}
</span>

具体实现:

<span style="font-family:SimSun;font-size:18px;">package linearList;

import java.util.Scanner;

import sun.net.www.content.text.plain;
import sun.rmi.runtime.Log;

public class DuLinkList implements ILiist{
	public DuLNode head;  //双向循环链表的头结点
	public DuLinkList(){
		head=new DuLNode();//初始化头结点
		head.prior=head;//初始化头结点的前驱和后继
		head.next=head;
	}
	
	//从表尾到表头逆向创建双向循环链表,n为结点个数
	public DuLinkList(int n)throws Exception{
		this();
		Scanner sc=new Scanner(System.in);
		for(int j=0;j<n;j++){
			insert(length(),sc.next());//生成新结点,插入到表头
		}
	}
	
	//在带头结点的双向循环链表中的插入操作
	public void insert(int i,Object x)throws Exception{
		DuLNode p=head.next;//初始化p,p指向首结点
		int j=0;//j为计数器
		while(!p.equals(head)&&j<i){//寻找插入位置i
			p=p.next;//指向后继结点
			++j;//计数器的值加1
		}
		if(j!=i&&!p.equals(head)){//i不合法,抛出异常
			throw new Exception("插入位置不合法");
		}
		DuLNode s=new DuLNode(x);//生成新结点
		
		p.prior.next=s;//将新生成的结点插入到第i个结点p的前面
		s.prior=p.prior;
		s.next=p;
		p.prior=s;
	}
	
	//在带头结点的双向循环链表中的删除操作
	public void remove(int i)throws Exception{
		DuLNode p=head.next;//初始化,p指向首结点
		int j=0;//j为计数器
		while(!p.equals(head)&&j<i){
			p=p.next;
			++j;
		}
		if(j!=i){
			throw new Exception("删除位置不合法");
		}
		p.prior.next=p.next;//使第i个结点p从链中脱离
		p.next.prior=p.prior;
	}
	
	//将一个已经存在的带头结点的双向循环链表置成为空表
		public void clear(){
			head.data=null;
			head.next=null;
			head.prior=null;
		}
		
		//判断带头结点的双向循环链表是否为空
		public boolean isEmpty(){
			return head.next==null;
		}
		
		//求带头结点的双向循环链表的长度
		public int length(){
			DuLNode p=head.next;//初始化,p指向首结点
			int length=0;//length为计数器
			while(!p.equals(head)){//从首结点开始向后查找,直到p为空
				p=p.next;//指向后继结点
				++length;//长度增一
			}
			return length;
		}
		
		// 按序号查找
		public Object get(int i) throws Exception{
			DuLNode p=head.next;//初始化,p指向首结点
			int j=0;//计数器
			while(!p.equals(head)&&j<i){//从首结点开始向后查找,直到p指向第i个结点或者p为空
				p=p.next;//指向后继结点
				++j;//计数器值加一
			}
			if(j>i||p==null){//i小于0或者大于表长时,即i不合法
				throw new Exception("第"+i+"个元素不存在");//抛出异常
			}
			return p.data;//返回结点p的数据域值
		}
	
		//按值查找
		public int indexOf(Object x){
			DuLNode p=head.next;//初始化,p指向头结点
			int j=0;//j为计数器
			
			//从链表的首结点开始寻找,直到找到p.data或者到达双向循环链表的表尾
			while(!p.equals(head)&&!p.data.toString().equals(x.toString())){
				p=p.next;//指向下一个结点
				++j;//计数器的值加1
			}
			if(!p.equals(head)){
				return j;//返回值为x的结点在双向循环链表中的位置
			}
			else {
				return -1;//不存在,返回-1
			}
		}
		
		public void display(){
			DuLNode node=head.next;//取出带头结点的双向循环链表中的首结点
			while(!node.equals(head)){
				System.out.printf(node.data+" ");//输出结点的值
				node=node.next;//取下一个结点
			}
			System.out.println();
		}
}
</span>