数据结构--双向循环链表
参考双循环链表就是头尾相连,并且每一个结点都可以指向它的前驱和后继的链表。
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数据”。 } }
主要代码分析
结果
参考: