参考双循环链表就是头尾相连,并且每一个结点都可以指向它的前驱和后继的链表。
java代码实现
package sy180923;
public class DoubleLink<T>
{
//表头
private DNode<T> mHead;
//节点个数
private int mCount;
public DoubleLink()
{
//链表表头 为空不存数据
mHead=new DNode<T>(null,null,null);
//表头的前驱后继都是自己
mHead.prev=mHead.next=mHead;
//没有节点,空的
mCount=0;
}
//返回节点数目
public int size()
{
return mCount;
}
//判断链表是否为空
public boolean isEmpty()
{
return mCount==0;
}
//获取index位置的节点
private DNode<T> getNode(int index)
{
if(index<0 || index>=mCount)
throw new IndexOutOfBoundsException();
//二分正着找
if(index<=mCount/2)
{
DNode<T> node=mHead.next;
for(int i=0;i<index;i++)
{
node=node.next;//指针下移,依次遍历
}
return node;
}
//表头的前一个就是最后一个
DNode<T> rnode=mHead.prev;
//比如 index=7,mCount=10
//就是从10-7-1=2(下标从0)
//就是找 10 9 的前面那个
int rindex=mCount-index-1;
for(int j=0;j<rindex;j++)
{
rnode=rnode.prev;
}
return rnode;
}
//获取index位置节点的值
public T get(int index)
{
return getNode(index).value;
}
public T getFirst()
{
return getNode(0).value;
}
public T getLast()
{
return getNode(mCount-1).value;
}
//前插
public void insert(int index,T t)
{
if(index==0)
{
DNode<T> node=new DNode<T>(t,mHead,mHead.next);
//跟自己串起来
mHead.next.prev=node;
mHead.next=node;
mCount++;
return;
}
//比如我要插在第二个数的前面 index=2
DNode<T>inode=getNode(index);
//新来一个节点,在这个下标前面
//这句话指的是这个新来的是inode的前驱是新来的前驱,inode是新来的后继
DNode<T>tnode=new DNode<T>(t,inode.prev,inode);
//inode的前一个的后继是这个新来的
inode.prev.next=tnode;
//inode.next=tnode;这不对
//改正如下
//inode的前一个是这个新来的
inode.prev=tnode;
mCount++;
return;
}
public void insertFirst(T t)
{
insert(0, t);
}
// 将节点追加到链表的末尾
public void appendLast(T t)
{
DNode<T> node=new DNode<T>(t,mHead.prev,mHead);
mHead.prev.next=node;
mHead.prev=node;
mCount++;
}
public void del(int index)
{
DNode<T>iNode=getNode(index);
iNode.prev.next=iNode.next;
iNode.next.prev=iNode.prev;
iNode=null;
mCount--;
}
public void deleteFirst()
{
del(0);
}
public void deleteLast()
{
del(mCount-1);
}
}
package sy180923;
//双向链表“节点”
public class DNode<T>
{
public DNode prev;//前驱
public DNode next;//后继
public T value;//存储类型的值
public DNode(T value,DNode prev, DNode next)
{
super();
this.prev = prev;
this.next = next;
this.value = value;
}
}
package sy180923;
public class DlinkTest
{
// 双向链表操作int数据
private static void int_test() {
int[] iarr = {10, 20, 30, 40};
System.out.println("\n----int_test----");
// 创建双向链表
DoubleLink<Integer> dlink = new DoubleLink<Integer>();
dlink.insert(0, 20); // 将 20 插入到第一个位置
dlink.appendLast(10); // 将 10 追加到链表末尾
dlink.insertFirst(30); // 将 30 插入到第一个位置
dlink.insert(2,40);
dlink.insert(3,70);
dlink.insert(2,80);
// 双向链表是否为空
System.out.printf("isEmpty()=%b\n", dlink.isEmpty());
// 双向链表的大小
System.out.printf("size()=%d\n", dlink.size());
// 打印出全部的节点
for (int i=0; i<dlink.size(); i++)
System.out.println("dlink("+i+")="+ dlink.get(i));
}
public static void main(String[] args) {
int_test(); // 演示向双向链表操作“int数据”。
}
}
结果
参考: