用链表实现双向队列
2016-03-02 21:42
489 查看
每个节点设置了指向前一节点与后一节点的引用pre与next,实现了队列两端增加删除元素的操作。
具体代码如下:
运行结果:
ok—>hello—>good—>thanks—>
all—>hello—>good—>do—>
good—>do—>
size:2
算法分析:
从时间复杂度上来说,除了显示队列的toString方法外,其他所有的操作都是常数。
从空间复杂度上来说,每个node节点占用48字节(对象开销16字节,内部类的额外开销8字节,3个引用共24字节)。对于Dequeue类来说大约有(20 + (48 + sizeof(Item))*(N+2))(包含tail与head节点,未计算填充字节)
具体代码如下:
import java.util.Iterator; import edu.princeton.cs.algs4.StdOut; public class Dequeue<Item> implements Iterable<Item>{ private Node head; private Node tail; private int length; /** * constructor */ public Dequeue() { // TODO Auto-generated constructor stub head = new Node(null); tail = new Node(null); } /** * is this queue empty? * @author Bjy_PC * * @param <Item> */ public boolean isEmpty() { return head.next == null; } /** * * @return length of queue */ public int size() { return length; } /** * insert item from left * @param item */ public void pushLeft(Item item) { Node node = new Node(item); Node oldnode = head.next; head.next = node; node.pre = head; node.next = oldnode; length++; if (tail.pre == null) { tail.pre = node; node.next = tail; } } /** * insert item from right * @param item */ public void pushRight(Item item) { Node node = new Node(item);; Node oldnode = tail.pre ; node.next = tail; node.pre = oldnode; tail.pre = node; oldnode.next = node; length++; if (head.next == null) { head.next = node; node.pre = head; } } /** * * @return the item deleted from left */ public Item popLeft() { Item item; if (isEmpty()) throw new java.lang.NullPointerException("dequeue is empty"); else { item = (Item) head.value; head.next = head.next.next; head.next.pre = head; length--; } return item; } /** * * @return the item deleted from right */ public Item popRight() { Item item; if (isEmpty()) throw new java.lang.NullPointerException("dequeue is empty"); else { item = (Item) tail.value; tail.pre = tail.pre.pre; tail.pre.next = tail; length--; } return item; } @Override public String toString() { // TODO Auto-generated method stub Node node = head.next; String string = new String(); while (node.value != null) { string += (String)node.value + "--->"; node = node.next; } return string; } @Override public Iterator<Item> iterator() { // TODO Auto-generated method stub return new dequeueIterator(); } private class dequeueIterator implements Iterator<Item> { Node Cur = head; @Override public boolean hasNext() { // TODO Auto-generated method stub return Cur != tail.pre; } @Override public Item next() { // TODO Auto-generated method stub Item item = (Item) Cur.next.value; Cur = Cur.next; return item; } } private class Node { Item value; Node next; Node pre; public Node(Item value) { // TODO Auto-generated constructor stub this.value = value; this.next = null; this.pre = null; } } public static void main(String[] args) { // TODO Auto-generated method stub Dequeue<String> dequeue = new Dequeue<String>(); dequeue.pushLeft("hello"); StdOut.println(dequeue); dequeue.pushRight("good"); StdOut.println(dequeue); dequeue.pushLeft("ok"); dequeue.pushRight("thanks"); dequeue.popRight(); dequeue.popLeft(); dequeue.pushLeft("all"); dequeue.pushRight("do"); dequeue.popLeft(); dequeue.popLeft(); dequeue.popLeft(); dequeue.popLeft(); for (String string : dequeue) { StdOut.println(string); } StdOut.println(dequeue); StdOut.println(dequeue.size()); } }
运行结果:
ok—>hello—>good—>thanks—>
all—>hello—>good—>do—>
good—>do—>
size:2
算法分析:
从时间复杂度上来说,除了显示队列的toString方法外,其他所有的操作都是常数。
从空间复杂度上来说,每个node节点占用48字节(对象开销16字节,内部类的额外开销8字节,3个引用共24字节)。对于Dequeue类来说大约有(20 + (48 + sizeof(Item))*(N+2))(包含tail与head节点,未计算填充字节)
相关文章推荐
- Flask Sqlalchemy数据库操作例程
- memcpy函数,我来了
- UVA 11995(p186)----I Can Guess the Data Structure!
- delphi 利用HTTP的POST方法做个在线翻译的小工具 good
- 类目,延展,协议的基本概念
- 选择Web API还是WCF
- 205_IsomorphicStrings
- Java中内存分配及堆栈比较
- dmesg
- Java 9终于要包含Jigsaw项目了
- Leetcode: 328. Odd Even Linked List(JAVA)
- Java 9终于要包含Jigsaw项目了
- SLua 优化初始化速度
- 12C ORA-错误汇总10 ORA-12500 to ORA-19400
- 基于XML配置的springMVC小案例
- jstl 简单实践
- 求两帧图像或着视频的光流(optical flow)
- iOS-App installation failed原因及解决方法
- 实现strcmp(字符串比较)
- 半年没有写工作周报,于是老板把我开除了