zoukankan      html  css  js  c++  java
  • 算法-第四版-练习1.3.33解答

    问题

    Deque。一个双向队列(或者称为deque)和栈或队列类似,但它同时支持在两端添加或删除元素。Deque能够存储一组元素并支持如下API。

    /**
     * ----------------------------------------------------- 
     * public class Deque<Item> implements Iterable<Item>
     * ----------------------------------------------------- 
     *              Deque()	             创建空双向队列
     *      boolean isEmpty()            双向队列是否为空
     *          int size()               双向队列中元素的数量
     *         void pushLeft(Item item)  向左端添加一个新元素
     *         void pushRight(Item item) 向右端添加一个新元素
     *         Item popLeft()            从左羰删除一个元素
     *         Item popRight()           从右羰删除一个元素
     * ----------------------------------------------------- 
     */
    编写一个使用双向链表实现这份API的Deque类。以及一个使用动态数据组调整实现这份API的ResizingArrayDeque类。

    解决思路

    该问题解决起来并不难。使用双向链表时需要注意每个结点的双向引用,不要只添加单向的引用或者只删除单向的引用。使用动态数组时注意,何时调整数组的大小以及将数组大小调整为多大。本实现添加元素时,只有在头部或者尾部没有空间时,才进行调整,调整为队列中元素的个数的3倍,前后各留队列中元素个数的长度。在删除元素,当元素的数量小于总长度的1/6时,进行调整,将长度调整为元素个数的3倍,同样前后各留元素个数的长度。注意最小不小于3。

    代码

    一共三个文件,分别为Deque类,ResizingArrayDeque类和测试文件E10333类。

    Deque类。
    package com.furzoom.lab.algs.ch103;
    
    import java.util.Iterator;
    /**
     * ----------------------------------------------------- 
     * public class Deque<Item> implements Iterable<Item>
     * ----------------------------------------------------- 
     *              Deque()              创建空双向队列
     *      boolean isEmpty()            双向队列是否为空
     *          int size()               双向队列中元素的数量
     *         void pushLeft(Item item)  向左端添加一个新元素
     *         void pushRight(Item item) 向右端添加一个新元素
     *         Item popLeft()            从左羰删除一个元素
     *         Item popRight()           从右羰删除一个元素
     * ----------------------------------------------------- 
     */
    public class Deque<Item> implements Iterable<Item> {
    
    	private Node head = null;
    	private Node tail = null;
    	private int size = 0;
    
    	private class Node {
    		public Item item;
    		public Node prev;
    		public Node next;
    	}
    
    	public boolean isEmpty() {
    		return head == null;
    	}
    
    	public int size() {
    		return size;
    	}
    
    	public void pushLeft(Item item) {
    		Node node = new Node();
    		node.item = item;
    		node.prev = null;
    		if (isEmpty()) {
    			head = tail = node;
    			node.next = null;
    		} else {
    			head.prev = node;
    			node.next = head;
    			head = node;
    		}
    		size++;
    	}
    
    	public void pushRight(Item item) {
    		Node node = new Node();
    		node.item = item;
    		node.next = null;
    		if (isEmpty()) {
    			head = tail = node;
    			node.prev = null;
    		} else {
    			tail.next = node;
    			node.prev = tail;
    			tail = node;
    		}
    		size++;
    	}
    
    	public Item popLeft() {
    		if (isEmpty()) {
    			return null;
    		} else {
    			Item e = head.item;
    			if (size() == 1) {
    				head = tail = null;
    			} else {
    				head = head.next;
    				head.prev.next = null;
    				head.prev = null;
    			}
    			size--;
    			return e;
    		}
    	}
    	
    	public Item popRight() {
    		if (isEmpty()) {
    			return null;
    		} else {
    			Item e = tail.item;
    			if (size() == 1) {
    				head = tail = null;
    			} else {
    				tail = tail.prev;
    				tail.next.prev = null;
    				tail.next = null;
    			}
    			size--;
    			return e;
    		}
    	}
    
    	@Override
    	public Iterator<Item> iterator() {
    		return new Iter();
    	}
    
    	private class Iter implements Iterator<Item> {
    		private Node current = head;
    		
    		@Override
    		public boolean hasNext() {
    			return current != null;
    		}
    
    		@Override
    		public Item next() {
    			Item e = current.item;
    			current = current.next;
    			return e;
    		}
    	}
    }
    


    ResizingArrayDeque类。
    package com.furzoom.lab.algs.ch103;
    
    import java.util.Iterator;
    
    public class ResizingArrayDeque<Item> implements Iterable<Item> {
    	private int head;
    	private int tail;
    	private Item[] deque;
    	
    	@SuppressWarnings("unchecked")
    	public ResizingArrayDeque() {
    		deque = (Item[])new Object[3];
    		head = 1;
    		tail = 1;
    	}
    	
    	public boolean isEmpty() {
    		return head == tail;
    	}
    	
    	public int size() {
    		return tail - head;
    	}
    	
    	public void pushLeft(Item item) {
    		if (head == 0) {
    			resize(3 * size());
    		}
    		deque[--head] = item;
    	}
    	
    	public void pushRight(Item item) {
    		if (tail == deque.length) {
    			resize(3 * size());
    		}
    		deque[tail++] = item;
    	}
    	
    	public Item popLeft() {
    		if (isEmpty()) {
    			return null;
    		}
    		if (size() * 6 < deque.length) {
    			resize(size() * 3);
    		}
    		return deque[head++];
    	}
    	
    	public Item popRight() {
    		if (isEmpty()) {
    			return null;
    		}
    		if (size() * 6 < deque.length) {
    			resize(size() * 3);
    		}
    		return deque[--tail];
    	}
    	
    	@SuppressWarnings("unchecked")
    	private void resize(int size) {
    		if (size < 3) {
    			size = 3;
    		}
    		Item tmp[] = (Item[])new Object[size];
    		int j = size / 3;
    		for (int i = head; i < tail; i++) {
    			tmp[j++] = deque[i];
    		}
    		deque = tmp;
    		head = size / 3;
    		tail = j;
    	}
    	
    	@Override
    	public Iterator<Item> iterator() {
    		return new Iter();
    	}
    	
    	private class Iter implements Iterator<Item> {
    		private int current = head;
    
    		@Override
    		public boolean hasNext() {
    			return current < tail;
    		}
    
    		@Override
    		public Item next() {
    			Item e = deque[current++];
    			return e;
    		}
    	}
    }
    




    测试代码:
    package com.furzoom.lab.algs.ch103;
    
    import java.util.Iterator;
    
    public class E10333 {
    
    	public static void main(String[] args) {
    //		Deque<String> deque = new Deque<String>();
    		ResizingArrayDeque<String> deque = new ResizingArrayDeque<String>();
    		deque.pushLeft("c");
    		deque.pushLeft("b");
    		deque.pushRight("d");
    		deque.pushRight("e");
    		System.out.println("deque size: " + deque.size());
    		Iterator<String> it = deque.iterator();
    		while (it.hasNext()) {
    			System.out.println(it.next());
    		}
    		System.out.println("Pop up from right: ");
    		while (!deque.isEmpty()) {
    			System.out.println(deque.popRight());
    		}
    		
    		deque.pushLeft("c");
    		deque.pushLeft("b");
    		deque.pushRight("d");
    		deque.pushRight("e");
    		System.out.println("Pop up from left: ");
    		while (!deque.isEmpty()) {
    			System.out.println(deque.popLeft());
    		}
    	}
    
    }
    



    结果
    deque size: 4
    b
    c
    d
    e
    Pop up from right: 
    e
    d
    c
    b
    Pop up from left: 
    b
    c
    d
    e
    




    作者:马 岩Furzoom) (http://www.cnblogs.com/furzoom/
    版权声明:本文的版权归作者与博客园共同所有。转载时请在明显地方注明本文的详细链接,未经作者同意请不要删除此段声明,感谢您为保护知识产权做出的贡献。
  • 相关阅读:
    Linux(CentOS)下安装OMNet++
    Linux(CentOS)安装JDK
    给电脑安装Linux系统(CentOS)
    OmNet++遇到的问题
    数论倒数总结
    [AHOI2007]密码箱
    [AHOI2005]约数研究
    Spark scala groupBy后求和
    Scala Seq创建简单的Spark DataFrame
    Spark DataFrame分组后选取第一行
  • 原文地址:https://www.cnblogs.com/furzoom/p/7710158.html
Copyright © 2011-2022 走看看