双链表--双端队列

1) 双链表在最前端和最后端各设置一个哑节点。这两个节点分别称为头结点和尾节点。头结点的next指向首节点,首节点的prev指向头结点。头结点其他域为null。尾节点的prev指向末节点,末节点的next指向尾节点。尾节点其他域为null。

  在链表为空时,头结点和尾节点已经存在了,并且此时头结点的next指向尾节点,尾节点的prev指向头结点。另外,再插入和删除时,有些修改指针指向的代码顺序不能修改。双链表实现代码如下:

 

  1 /**
  2  * Created by hfz on 2016/8/3.
  3  */
  4 /*
  5 双链表在最前端和最后端各设置一个哑节点。这两个节点分别称为头结点和尾节点。
  6 头结点的next指向首节点,首节点的prev指向头结点。头结点其他域为null
  7 尾节点的prev指向末节点,末节点的next指向尾节点。尾节点其他域为null。
  8 在链表为空时,头结点和尾节点已经存在了,并且此时头结点的next指向尾节点,尾节点的prev指向头结点。
  9 另外,再插入和删除时,有些修改指针指向的代码顺序不能修改。
 10  */
 11 public class DList {
 12     private DNode headNode;
 13     private DNode tailNode;
 14     private int size;
 15     /*
 16      */
 17     public DList(){
 18         headNode=new DNode();
 19         tailNode=new DNode();
 20         headNode.setNext(tailNode);
 21         tailNode.setPrev(headNode);
 22         size=0;
 23     }
 24     /*
 25     以下方法对链表为空时,同样适用,不必做特殊处理
 26      */
 27     
 28     public void addAtHeader(Object obj){//以下修改指针指向的代码顺序不能修改
 29         DNode node=new DNode(obj,headNode,headNode.getNext());
 30         headNode.getNext().setPrev(node);
 31         headNode.setNext(node);
 32         size++;
 33         System.out.println(String.format("在头结点插入%s",(String)obj));
 34     }
 35     /*
 36     以下方法当链表只有一个元素时同样适用,不用做特殊处理。
 37      */
 38     public void removeAtHeader(){
 39         if(size>0){
 40             DNode removedNode=headNode.getNext();
 41             removedNode.getNext().setPrev(headNode);
 42             headNode.setNext(removedNode.getNext());
 43             size--;
 44             System.out.println(String.format("在头结点删除%s", (String)removedNode.getEle()));
 45         }
 46         else{
 47             System.out.println("链表为空,无元素可删除!");
 48         }
 49     }
 50     /*
 51     以下方法对链表为空时,同样适用,不必做特殊处理
 52      */
 53     public void addAtTail(Object obj){
 54         DNode node =new DNode(obj,tailNode.getPrev(),tailNode);
 55         tailNode.getPrev().setNext(node);
 56         tailNode.setPrev(node);
 57         size++;
 58         System.out.println(String.format("在尾结点插入%s",(String)obj));
 59     }
 60     /*
 61        以下方法当链表只有一个元素时同样适用,不用做特殊处理。
 62         */
 63     public void removeAtTail(){
 64         if(size>0){
 65             DNode removedNode=tailNode.getPrev();
 66             tailNode.setPrev(removedNode.getPrev());
 67             removedNode.getPrev().setNext(tailNode);
 68             size--;
 69             System.out.println(String.format("在尾结点删除%s", (String)removedNode.getEle()));
 70 
 71         }
 72         else {
 73             System.out.println("链表为空,无元素可删除!");
 74         }
 75     }
 76     public int getSize(){
 77         return size;
 78     }
 79     //test
 80     public static void main(String[] args){
 81         DList doubleList=new DList();
 82         doubleList.addAtHeader("A1");
 83         doubleList.addAtHeader("A2");
 84         doubleList.addAtHeader("A3");
 85         doubleList.addAtHeader("A4");
 86         doubleList.addAtHeader("A5");
 87         doubleList.addAtHeader("A6");
 88         doubleList.removeAtHeader();
 89         doubleList.removeAtHeader();
 90         doubleList.removeAtHeader();
 91         doubleList.removeAtHeader();
 92         doubleList.removeAtHeader();
 93         doubleList.removeAtHeader();
 94         doubleList.removeAtHeader();
 95         doubleList.addAtTail("B1");
 96         doubleList.addAtTail("B2");
 97         doubleList.addAtTail("B3");
 98         doubleList.addAtTail("B4");
 99         doubleList.addAtTail("B5");
100         doubleList.addAtTail("B6");
101         doubleList.removeAtTail();
102         doubleList.removeAtTail();
103         doubleList.removeAtTail();
104         doubleList.removeAtTail();
105         doubleList.removeAtTail();
106         doubleList.removeAtTail();
107         doubleList.removeAtTail();
108         doubleList.addAtHeader("C1");
109         doubleList.addAtHeader("C2");
110         doubleList.addAtTail("B2");
111         doubleList.addAtTail("B3");
112         doubleList.addAtTail("B4");
113         doubleList.addAtTail("B5");
114         doubleList.addAtHeader("A3");
115         doubleList.addAtHeader("A4");
116         doubleList.addAtHeader("A5");
117         doubleList.addAtHeader("A6");
118         doubleList.removeAtHeader();
119         doubleList.removeAtHeader();
120         doubleList.removeAtHeader();
121         doubleList.removeAtTail();
122         doubleList.removeAtTail();
123     }
124 }
125 /*
126 单链表中每个节点只有一个指向后继节点的指针,而双链表中,每个节点还多了一个指向前驱结点的指针
127  */
128 
129 class DNode{
130     private Object ele;
131     private DNode prev;
132     private DNode next;
133     public DNode(){
134         this(null,null,null);
135     }
136     public DNode(Object ele,DNode prev,DNode next){
137         this.ele=ele;
138         this.prev=prev;
139         this.next=next;
140     }
141     public Object getEle(){
142         return ele;
143     }
144     public void setEle(Object obj){
145         ele=obj;
146     }
147 
148     public DNode getPrev(){
149         return prev;
150     }
151 
152     public void setPrev(DNode node){
153         prev=node;
154     }
155 
156     public DNode getNext(){
157         return next;
158     }
159     public void setNext(DNode node){
160         next=node;
161     }
162 
163 }
View Code

 

 2)双端队列,就是前端和后端都支持插入和删除的队列。可以参考基于单链表的队列实现,来实现基于双链表的双端队列的实现。基于双链表的双端队列,各方法时间复杂度如下图所示:

posted @ 2016-08-03 10:06  lz3018  阅读(921)  评论(0编辑  收藏  举报