您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法之链表4---双向链表

2014-09-25 00:00 573 查看
在单链表的删除中,由于单向链表中只包含指向其后继节点的引用,所以无法立即访问到它的前驱节点。所以在删除的方法中我们借助一个循环来寻找tail的前驱节点。尽管这个前驱节点可以说可见不可达,但是为了删除它仍然不得不扫描整个链表才能恰好停在tail的前一个节点处。对一个长链表,或者是需要频繁执行这个删除方法的情况,会严重妨碍处理链表的速度。为了避免这个问题,可以重新定义链表,使表中每一个节点有两个引用雨,一个指向其前驱节点,一个指向其后继节点。这种链表叫做双向链表

一、双向链表的类的定义

class DoubleLinkNode{    public int info;    public DoubleLinkNode next;    public DoubleLinkNode prev;    public DoubleLinkNode(int e1)
{this(e1,null,null);
}    public DoubleLinkNode(int e1,DoubleLinkNode next, DoubleLinkNode prev){    this.info=e1;this.next=next;this.prev=prev;
}
}

 

二、双向链表的基本操作的实现(重点讲解删除和插入)

插入:双向链表的插入需要一下步骤:将e节点插入到a和b中





具体实现过程如下:

1)创建一个空节点

2)将其info域设置为e

3)将e的前驱节点指向a

4)将e的后继节点指向b

5)将b的前驱节点指向e

6)将a的后继节点指向e

注意:步骤3)和步骤4)可以调换顺序,但是步骤5)不能先执行否则会使得a.next提前变成了s,使得插入工作无法进行。我们可以理解为,先搞定s的前趋和后继,再搞定后节点的前趋,最后解决前节点的后继。

/* * 在指定位置后插入一个节点     */public void add(int e1, int insertData){

DoubleLinkNode tmp=head;    while(tmp!=null){if(tmp.info==e1){
DoubleLinkNode insert=new DoubleLinkNode(insertData);
insert.prev=tmp;
insert.next=tmp.next;
tmp.next.prev=insert;
tmp.next=insert;
}
}

}/* * 在头部插入一个节点     */public void addToHead(int e1){    if(!isEmpty())
{
head=new DoubleLinkNode(e1, head, null);
head.next.prev=head;
}    else{
head=tail=new D
3ff0
oubleLinkNode(e1);
}

}/* * 在尾部插入一个节点     */public void addToTail(int e1){    if(!isEmpty()){
tail=new DoubleLinkNode(e1, null, tail);
tail.prev.next=tail;
}else{
head=tail=new DoubleLinkNode(e1);
}

}


删除节点

删除节点需要考虑以下的几种情况:

1)在一个空链表中删除一个节点

2)在表尾删除节点

3)在表中删除节点

4)在表头删除节点

5)在只含有一个节点的链表中删除一个节点

删除的代码如下:

/* * 在表尾删除一个节点:时间复杂度O(1)     */public int deleteFromTail()
{if(!isEmpty())
{int e1=tail.info;if(head==tail)//只有一个节点的情况   head=tail=null;else{
tail=tail.prev;
tail.next=null;
}return e1;
}return 0;
}/* * 在表中删除节点:时间复杂度O(n)     */public int delete(int e1){

DoubleLinkNode tmp=head;int data;    if(tmp!=null){for(tmp=head;tmp!=null&&tmp.info!=e1;tmp=tmp.next);
tmp.prev.next=tmp.next;
tmp.next.prev=tmp.prev;
data=tmp.info;return data;
}return 0;

}/* * 在表头删除节点:时间复杂度O(1)     */public int deleteFromHead()
{if(!isEmpty())
{int e1=head.info;if(head==tail)
head=tail=null;else{
head=head.next;
head.prev=null;
}return e1;
}return 0;
}


 

双向链表的基本操作完整代码如下:

package com.linkedlist;public class DoubleLinkedList {    private DoubleLinkNode head,tail;    public DoubleLinkedList(){
head=tail=null;
} /* * 判断链表是否为空 */public boolean isEmpty(){return head==null;
}/* * 置空链表 */public void setToNull()
{
head=tail=null;
} /* * 在指定位置后插入一个节点:时间复杂度O(n) */public void add(int e1, int insertData){

DoubleLinkNode tmp=head; if(tmp!=null){for(tmp=head;tmp!=null;tmp=tmp.next)if(tmp.info==e1){
DoubleLinkNode insert=new DoubleLinkNode(insertData);
insert.prev=tmp;
insert.next=tmp.next;
tmp.next.prev=insert;
tmp.next=insert;
}
}

}/* * 在头部插入一个节点:时间复杂度O(1) */public void addToHead(int e1){ if(!isEmpty())
{
head=new DoubleLinkNode(e1, head, null);
head.next.prev=head;
} else{
head=tail=new DoubleLinkNode(e1);
}

}/* * 在尾部插入一个节点:时间复杂度O(1) */public void addToTail(int e1){ if(!isEmpty()){
tail=new DoubleLinkNode(e1, null, tail);
tail.prev.next=tail;
}else{
head=tail=new DoubleLinkNode(e1);
}

}/* * 在表尾删除一个节点:时间复杂度O(1) */public int deleteFromTail() {if(!isEmpty()) {int e1=tail.info;if(head==tail)//只有一个节点的情况 head=tail=null;else{ tail=tail.prev; tail.next=null; }return e1; }return 0; }/* * 在表中删除节点:时间复杂度O(n) */public int delete(int e1){ DoubleLinkNode tmp=head;int data; if(tmp!=null){for(tmp=head;tmp!=null&&tmp.info!=e1;tmp=tmp.next); tmp.prev.next=tmp.next; tmp.next.prev=tmp.prev; data=tmp.info;return data; }return 0; }/* * 在表头删除节点:时间复杂度O(1) */public int deleteFromHead() {if(!isEmpty()) {int e1=head.info;if(head==tail) head=tail=null;else{ head=head.next; head.prev=null; }return e1; }return 0; }/* * 查找:时间复杂度O(n) */public int find(int e1)
{
DoubleLinkNode tmp; for(tmp=head;tmp!=null&&tmp.info!=e1;tmp=tmp.next);if(tmp==null)return 0;elsereturn tmp.info;

}/* * 遍历节点:时间复杂度O(n) */public void printAll(){ for(DoubleLinkNode tmp=head;tmp!=null;tmp=tmp.next)
{
System.out.print(tmp.info+" ");
}
} public static void main(String[] args){

DoubleLinkedList list=new DoubleLinkedList(); int[] a=new int[10]; for(int i=0;i<10;i++)
{
a[i]=i+1;
} for(int i=0;i<10;i++)
{
list.addToTail(a[i]);
}
System.out.println("新的双向链表如下:");
list.printAll();

list.add(5, 11);
System.out.println("插入11后的链表如下:");
list.printAll();

list.delete(6);
System.out.println("删除6后的链表如下:");
list.printAll();
}
}class DoubleLinkNode{ public int info; public DoubleLinkNode next=null; public DoubleLinkNode prev=null; public DoubleLinkNode(int e1)
{this.info=e1;
} public DoubleLinkNode(int e1,DoubleLinkNode next, DoubleLinkNode prev){ this.info=e1;this.next=next;this.prev=prev;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息