算法练习(52): 双向队列与栈(1.3.48-1.3.50)

本系列博客习题来自《算法(第四版)》,算是本人的读书笔记,如果有人在读这本书的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(算法交流),想要加入的,请添加我的微信号:zhujinhui207407 谢谢。另外,本人的个人博客 http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

算法(第4版)

知识点

  • 队列、栈或 steque

题目

1.3.48 双向队列与栈。用一个双向队列实现两个栈,保证每个栈操作只需要常数次的双向队列操作。(请见练习 1.3.33)


1.3.48 Two stacks with a deque. Implement two stacks with a single deque so that each operation takes a constant number of deque operations (see Exercise 1.3.33).

分析

要实现一个栈,即是实现栈的 push,pop 等操作。

public class  Stack {
    private int N = 0;
    private Node topNode = null;
    private class Node {
        Item item;
        Node next;
    }

    private Deque deque;


    public void push(Item item) {
        if (deque == null) {
            deque = new Deque();
        }
        deque.pushRight(item);
    }

    public Item pop() {
        return deque.popRight();
    }

    public boolean isEmpty() {
        return deque.isEmpty();
    }

    public int size() {
        return deque.size();
    }
}

测试用例

 public static void main(String[] args) {
    Stack stack = new Stack();
    stack.push("I");
    stack.push("am");
    stack.push("Kyson");
    stack.push("You");
    stack.push("are");

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());


    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());
}

题目

1.3.49 栈与队列。用三个栈实现一个队列,保证每个队列操作(在最坏情况下)都只需要常数次的栈操作。


1.3.49 Queue with three stacks. Implement a queue with three stacks so that each queue operation takes a constant (worst-case) number of stack operations. Warning : high degree of difficulty.

分析

queue.new() : Stack1 = Stack.new();  
              Stack2 = Stack1;  

enqueue(element): Stack3 = Stack.new(); 
                  Stack3.push(element); 
                  Stack2.push(Stack3);
                  Stack3 = Stack.new();
                  Stack2.push(Stack3);
                  Stack2 = Stack3;                       

dequeue(): Stack3 = Stack1.pop(); 
           Stack1 = Stack1.pop();
           dequeue() = Stack1.pop()
           Stack1 = Stack3;

isEmtpy(): Stack1.isEmpty();

演示如下:

 | | | |3| | | |
 | | | |_| | | |
 | | |_____| | |
 | |         | |
 | |   |2|   | |
 | |   |_|   | |
 | |_________| |
 |             |
 |     |1|     |
 |     |_|     |
 |_____________|

题目

1.3.50 快速出错的迭代器。修改 Stack 的迭代器代码,确保一旦用例在迭代器中(通过 push() 或 pop() 操作)修改集合数据就抛出一个 java.util.ConcurrentModificationException 异常。


1.3.50 Fail-fast iterator. Modify the iterator code in Stack to immediately throw a java.util.ConcurrentModificationException if the client modifies the collection (via push() or pop()) during iteration? b).
Solution: Maintain a counter that counts the number of push() and pop() operations. When creating an iterator, store this value as an Iterator instance variable. Before each call to hasNext() and next(), check that this value has not changed since con- struction of the iterator; if it has, throw the exception.

答案

public class Stack implements Iterable
{
    private int N;
    private Node first;
    private int pushPopCount;
    
    private class Node {
        Item item;
        Node next;
    }
    
    public Stack() {
    }
    
    public Stack(Stack s)
    {
        Node right=new Node();
        Node oldright;
        for(Object i:s) {
            oldright=right;
            right=new Node();
            right.item=(Item) i;
            right.next=null;
            if(isEmpty()) {
                first=right;
            } else {
                oldright.next=right;
            }
            N++;
        }
    }
    
    public boolean isEmpty() {
        return N==0;
    }
    
    public int size() {
        return N;
    }
    
    public void push(Item item) {
        Node oldfirst=first;
        first=new Node();
        first.item=item;
        first.next=oldfirst;
        N++;
        pushPopCount++;
    }
    
    public Item pop() {
        Item item=first.item;
        first=first.next;
        N--;
        pushPopCount++;
        return item;
    }
    
    
    public Item peek() {
        Item item=first.item;
        return item;
    }
    
    public void catenation(Stack s) {
        while(!s.isEmpty()) {
            this.push((Item)s.pop());
        }
    }
    
    public Iterator iterator() {
        return new ListIterator();
    }
    
    private class ListIterator implements Iterator {
        private Node current=first;
        private int originatedPushPopCount;
        public ListIterator() {
            originatedPushPopCount=pushPopCount;
        }
        public boolean hasNext() {
            return current!=null;
        }
        public void remove(){}
        public Item next()
        {
            if(originatedPushPopCount!=pushPopCount)
                throw new java.util.ConcurrentModificationException();
            Item item=current.item;
            current=current.next;
            return item;
        }
    }
}

参考

How to implement a queue with three stacks?

广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

你可能感兴趣的:(算法练习(52): 双向队列与栈(1.3.48-1.3.50))