公用接口:
<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>