记得在一个公司面试上有一道题,写一个双向链表,包含链表的基本操作,插入,删除,获取长度等操作,由于时间匆忙,代码写的比较乱,连自己都没眼看了,后来细想自己从来都没有细心的写过数据结构,总觉得只要原理明白了就万事大吉了,事实证明,理论和实践还是有很大差距的。水平有限,如果有错误,还请不吝赐教
定义一个内部类Node用于存储节点元素
class Node {
private Node previous;//前驱节点
private Node next;//后继节点
private E e;//泛型元素值
public Node(Node previous, Node next, E e) {
this.previous = previous;
this.next = next;
this.e = e;
}
双向链表的关键在于节点指针的转移
下面以removeElement(E value)
为例简单介绍
public void removeElement(E value){
Node index=this.first;//创建index节点指向first节点
while(index!=null){
if(index.e==value)break;
index=index.next;
}//while循环用于遍历整个链表来获取指向要删除的节点指针
index.previous.next=index.next;
index.next.previous=index.previous;
length--;
}
index.previous
表示要删除节点的前驱节点index.previous.next=index.next;
意思是将前驱节点的后项指针指向要删除节点的后继节点
同理index.next
表示要删除节点的后继节点index.next.previous=index.previous;
意思是将后继节点的前向指针指向要删除节点的前驱节点可能有点绕,简单画个链表结构图就可以很明了了
insertNext(E baseElement,E value)
和insertPrevious(E baseElement,E value)
同理,这里不再赘述
DoubleLinkedList包含两个节点指针(伪指针,java中没有指针的概念)first和last,分别指向链表的第一个元素和最后一个元素
整体代码
public class DoubleLinkedList<E> {
private Node first;//指向第一个元素
private Node last;//指向最后一个元素
private int length=0;//链表长度
class Node {
private Node previous;
private Node next;
private E e;
public Node(Node previous, Node next, E e) {
this.previous = previous;
this.next = next;
this.e = e;
}
}
/***
* 向头节点添加元素,节点结构对外应该是不可见的,所以这里只传递一个泛型的值e
*/
public void addFirst(E e) {
if (first == null) {//链表为空判断
Node node = new Node(null, null, e);//创建一个新的节点,前驱和后继都为空
this.first = node;
this.last=node;//将first和last指针指向链表的第一个元素
length++;//链表长度自增一,下同
}else{
Node node=new Node(null,first,e);//链表不为空创建一个前驱为空,后继为当前first节点的节点,值为传入的参数e
this.first.previous=node;//当前first的前驱设置为node
this.first=node;//将first指针指向新节点
length++;
}
}
/***
*addLast同addFirst
*/
public void addLast(E e) {
if (last == null) {
Node node = new Node(null, null, e);
this.first = node;
this.last=node;
length++;
}else{
Node node=new Node(last,null,e);
this.last.next=node;
this.last=node;
length++;
}
}
public void insertPrevious(E baseElement,E value){
Node index=this.first;
while(index!=null){
if(index.e==baseElement)break;
index=index.next;
}
Node insertValue=new Node(index.previous,index,value);
index.previous.next=insertValue;
index.previous=insertValue;
length++;
}
public void insertNext(E baseElement,E value){
Node index=this.first;
while(index!=null){
if(index.e==baseElement)break;
index=index.next;
}
Node insertValue=new Node(index,index.next,value);
index.next.previous=insertValue;
index.next=insertValue;
length++;
}
public void removeElement(E value){
Node index=this.first;
while(index!=null){
if(index.e==value)break;
index=index.next;
}
index.previous.next=index.next;
index.next.previous=index.previous;
length--;
}
public int getLength(){
return length;
}
@Override
public String toString() {
StringBuffer sb=new StringBuffer();
Node current=this.first;
while(current!=null){
sb.append(current.e+"->");
current=current.next;
}
return sb.toString();
}
public static void main(String[] args) {
DoubleLinkedList<String> list=new DoubleLinkedList<>();
list.addLast("value1");
list.addLast("value2");
list.addLast("value3");
list.addLast("value4");
list.addFirst("value0");
list.insertPrevious("value3","insertValue");
list.insertNext("value3","insertValue2");
System.out.println(list.toString());
System.out.println("链表的长度是"+list.getLength());
list.removeElement("value3");
System.out.println(list.toString());
System.out.println("链表的长度是"+list.getLength());
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。