今天要实现的是双向链表,其优点在什么地方呢?传统链表的一个问题是沿着链表的反向遍历是和困难的。双向链表具备这个能力,允许向前和向后遍历,其秘密在于每个链结点有两个指向其他链接点的引用,而不是一个。
它的缺点是每次插入删除一个链结点的时候,要处理四个链结点的引用,而不是两个。两个连接前一个结点,2个连接后一结点。而且占用空间也大了一些。
具体的删除,插入过程就是对4个链接点引用的处理过程,内容有些繁琐,结合图像并且自己在纸上手画一下处理的过程会更好理解。下面显示的是加上注释的代码。对各个重要类变量函数都有说明。
链节点 Link:
- package DoublyLinklist;
- public class Link {
- public int iData;
- public Link previous;
- public Link next;
- //......................................................
- public Link(int d)
- {
- iData=d;
- }
- //......................................................
- public void displayLink()
- {
- System.out.print(iData+" ");
- }
- //......................................................
- }
双向链表类DoublyLinkedList
- package DoublyLinklist;
- public class DoublyLinkedList
- {
- private Link first;
- private Link last;
- //......................................................
- public DoublyLinkedList()//constructor
- {
- first=null;
- last=null;
- }
- //......................................................
- public boolean isEmpty()//true is list is empty
- {return first==null;}
- //......................................................
- public void insertFirst(int d)
- {
- Link newLink=new Link(d);//产生一个Link对象
- if(isEmpty())last=newLink;//如果链表空,newlink也为last节点
- else
- first.previous=newLink;//非空,把newlink<--old first(这个是指向)
- newLink.next=first; //newlink-->old first(这个是指向)
- first=newLink;//first==>newlink(这个是等同)
- }
- //......................................................
- public void insertLast(int d)//在链表尾插入
- {
- Link newLink=new Link(d);
- if(isEmpty())first=newLink;//考虑空的情况
- else
- {
- last.next=newLink; //last-->newlink
- newLink.previous=last;//last<--newlink
- }
- last=newLink;//last<==newlink
- }
- //......................................................
- public Link deleteFirst()//删除首节点
- {
- Link temp=first;
- if(first.next==null)last=null;//考虑链表只有一个节点情况
- else
- first.next.previous=null;//非空则断绝old first与删除后链表的联系
- first=first.next;//首节点后移
- return temp;//返回删除节点
- }
- //......................................................
- public Link deleteLast()// 删除末节点
- {
- Link temp=last;
- if(first.next==null)first=null;//考虑链表只有一个节点情况
- else
- last.previous.next=null;//非空则断绝old last与删除后链表的联系
- last=last.previous;//末节点前移
- return temp;//返回删除节点
- }
- //......................................................
- public boolean insertAfter(int key,int d) //查找链表中的值等于key的节点,在其后面插入数据d
- {
- Link current=first;//current"指针"指向first
- while(current.iData!=key)//匹配循环条件
- {
- current=current.next;
- if(current==null)return false;//扫描完整个链表无匹配返回false
- }
- Link newLink=new Link(d);//新的节点对象
- if(current==last)//如果链表最后一个节点匹配key
- {
- newLink.next=null;//解决newlink的向后的指向
- last=newLink; //
- }
- else
- {
- newLink.next=current.next;//
- current.next.previous=newLink;//一般情况下的newlink跟后一个节点之间的依赖关系
- }
- current.next=newLink;//newlink和前一个节点的依赖关系建立
- newLink.previous=current;//
- return true;
- }
- //......................................................
- public Link deleteKey(int d)
- {
- Link current=first;
- while(current.iData!=d)
- {
- current=current.next;
- if(current==null)return null;
- }
- if(current==first)
- first.next.previous=null;//考虑删除节点后向前依赖关系问题,首节点是特例
- else //
- current.next.previous=current.previous;
- if(current==last)
- last.previous.next=null;//考虑删除节点后向后依赖关系问题,末节点为特例
- else //
- current.previous.next=current.next;
- return current;
- }
- //......................................................
- public void displayForward()
- {
- System.out.print("List(first-->last):");
- Link current=first;
- while(current!=null)
- {
- current.displayLink();
- current=current.next;
- }
- System.out.println("");
- }
- //......................................................
- public void displayBackward()
- {
- System.out.print("List(last-->first):");
- Link current=last;
- while(current!=null)
- {
- current.displayLink();
- current=current.previous;
- }
- System.out.println("");
- }
- }
应用类
- package DoublyLinklist;
- public class DoublyLinkedApp {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- DoublyLinkedList theList=new DoublyLinkedList();
- theList.insertFirst(22);
- theList.insertFirst(44);
- theList.insertFirst(66);
- theList.insertLast(11);
- theList.insertLast(33);
- theList.insertLast(55);
- theList.displayForward();
- theList.displayBackward();
- theList.deleteFirst();
- theList.deleteLast();
- theList.deleteKey(11);
- theList.displayForward();
- theList.insertAfter(22, 77);
- theList.insertAfter(33, 88);
- theList.displayForward();
- }
- }
结果显示:
- List(first-->last):66 44 22 11 33 55
- List(last-->first):55 33 11 22 44 66
- List(first-->last):44 22 33
- List(first-->last):44 22 77 33 88