1.3 Bags, Queues, and Stacks(算法 Algorithms 第4版)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.3 Bags, Queues, and Stacks(算法 Algorithms 第4版)相关的知识,希望对你有一定的参考价值。

1.3.1

package com.qiusongde;

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class FixedCapacityStackOfStrings implements Iterable<String> {
    
    private String[] a;
    private int n;

    public FixedCapacityStackOfStrings(int cap) {
        a = new String[cap];
        n = 0;
    }
    
    public void push(String item) {
        if(isFull())
            throw new IndexOutOfBoundsException("FiexdCapcityStackOfString is Full");
        a[n++] = item;
    }
    
    public String pop() {
        if(isEmpty())
            throw new NoSuchElementException("FiexdCapcityStackOfString is empty");
        return a[--n];
    }
    
  //1.3.1
public boolean isFull() { return n == a.length; } public boolean isEmpty() { return n == 0; } public int size() { return n; } @Override public Iterator<String> iterator() { return new ReverseArrayIterator(); } private class ReverseArrayIterator implements Iterator<String> { private int i = n; @Override public boolean hasNext() { return i > 0; } @Override public String next() { return a[--i]; } } public static void main(String[] args) { int max = 5; FixedCapacityStackOfStrings stack = new FixedCapacityStackOfStrings(max); StdOut.println("stack initialized max size is:" + max); while (!StdIn.isEmpty()) { String item = StdIn.readString(); if (!item.equals("-")) { if(stack.isFull()) StdOut.println("push error, stack full"); else { stack.push(item); StdOut.println("push success:" + item + " size:" + stack.size()); StdOut.print("Left on stack: "); for (String s : stack) { StdOut.print(s + " "); } StdOut.println(); } } else { if(stack.isEmpty()) StdOut.println("pop error, stack empty"); else { StdOut.println("pop success:" + stack.pop() + " size:" + stack.size()); StdOut.print("Left on stack: "); for (String s : stack) { StdOut.print(s + " "); } StdOut.println(); } } } } }
stack initialized max size is:5
to
push success:to size:1
Left on stack: to 
be
push success:be size:2
Left on stack: be to 
or
push success:or size:3
Left on stack: or be to 
not
push success:not size:4
Left on stack: not or be to 
to
push success:to size:5
Left on stack: to not or be to 
be
push error, stack full
-
pop success:to size:4
Left on stack: not or be to 
-
pop success:not size:3
Left on stack: or be to 
-
pop success:or size:2
Left on stack: be to 
-
pop success:be size:1
Left on stack: to 
-
pop success:to size:0
Left on stack: 
-
pop error, stack empty

 

1.3.2

was best times of the was the it (1 left on stack)

 

1.3.3

(a)  4 3 2 1 0 9 8 7 6 5

(b)  4 6 8 7 5 3 2 9 0 1

(c)  2 5 6 7 4 8 9 3 1 0

(d)  4 3 2 1 0 5 6 7 8 9

(e)  1 2 3 4 5 6 9 8 7 0

(f)  0 4 6 5 3 8 1 7 2 9

(g)  1 4 7 9 8 6 5 3 0 2

(h)  2 1 4 3 6 5 8 7 9 0

解题思路:

因为栈是后进先出的,又是按0到9这个顺序进行压栈的(push),因此如果pop出了某个值x,则后边比x小的值出现的顺序必须是逆序的。

举例,如果出现了4,则后边0 1 2 3出现的顺序必须是逆序的。

b中0 1不满足要求。

f中3 1 2不满足要求。

g中3 0 2不满足要求。

 

1.3.4

主要思路:

遇到左括号则一直压栈,遇到右括号时则从栈中弹出一个元素。

如果此时栈为空,则返回false。

如果这个元素与右括号不匹配,则返回false。

重复此过程,最后判断栈是否为空,若为空则返回true,否则返回false。

//1.3.4
//parentheses
package com.qiusongde;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Parentheses {

    private static final char LEFT_PAREN     = ‘(‘;
    private static final char RIGHT_PAREN    = ‘)‘;
    private static final char LEFT_BRACE     = ‘{‘;
    private static final char RIGHT_BRACE    = ‘}‘;
    private static final char LEFT_BRACKET   = ‘[‘;
    private static final char RIGHT_BRACKET  = ‘]‘;
    
    public static void main(String[] args) {
        String input = StdIn.readAll().trim();
        StdOut.println("input:" + input);
        StdOut.println(isParenBalanced(input));
    }
    
    public static boolean isParenBalanced(String input) {
        
        Stack<Character> stack = new Stack<Character>();
        
        for(int i = 0; i < input.length(); i++) {
            
            char pare = input.charAt(i);
            
            if(pare == LEFT_PAREN)
                stack.push(pare);
            if(pare == LEFT_BRACE)
                stack.push(pare);
            if(pare == LEFT_BRACKET)
                stack.push(pare);
            
            if(pare == RIGHT_PAREN) {
                if(stack.isEmpty())
                    return false;
                if(stack.pop() != LEFT_PAREN)
                    return false;
            }
            
            if(pare == RIGHT_BRACE) {
                if(stack.isEmpty())
                    return false;
                if(stack.pop() != LEFT_BRACE)
                    return false;
            }
            
            if(pare == RIGHT_BRACKET) {
                if(stack.isEmpty())
                    return false;
                if(stack.pop() != LEFT_BRACKET)
                    return false;
            }
        }
        
        if(stack.isEmpty())
            return true;
        else
            return false;
    }

}

技术分享

技术分享

 

1.3.5

输出N的二进制表示

 

1.3.6

反转队列q的元素顺序

 

1.3.7

package com.qiusongde;

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Stack<Item> implements Iterable<Item> {

    private Node first;
    private int n;
    
    private class Node {
        Item item;
        Node next;
    }
    
    public Stack() {
        first = null;
        n = 0;
    }
    
    public void push(Item item) {
        Node oldfirst = first;
        
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        
        n++;
    }
    
    public Item pop() {
        
        if(isEmpty()) 
            throw new NoSuchElementException("Stack is empty");
        
        Item item = first.item;
        first = first.next;
        n--;
        
        return item;
    }
    
    //1.3.7
    public Item peek() {
        if(isEmpty())
            throw new NoSuchElementException("Stack is empty");
        
        return first.item;
    }
    
    public boolean isEmpty() {
        return first == null;
    }
    
    public int size() {
        return n;
    }

    @Override
    public Iterator<Item> iterator() {
        
        return new StackIterator();
    }
    
    private class StackIterator implements Iterator<Item> {

        private Node current = first;
        
        @Override
        public boolean hasNext() {
            return current != null;
        }

        @Override
        public Item next() {
            if(!hasNext())
                throw new NoSuchElementException("Stack is empty");
            
            Item item = current.item;
            current = current.next;
            
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Stack don‘t support remove");
        }
        
    }
    
    public static void main(String[] args) {
        
        Stack<String> stack = new Stack<String>();
        StdOut.println("Initialized size:" + stack.size());
        
        while (!StdIn.isEmpty()) {
            
            String item = StdIn.readString();
            
            if (!item.equals("-")) {
                
                stack.push(item); 
                StdOut.println("push success:" + item + " size:" + stack.size());
                
                StdOut.print("Left on stack: ");
                for (String s : stack) {
                    StdOut.print(s + " ");
                }
                StdOut.println();
                
            } else {
                if(stack.isEmpty())
                    StdOut.println("pop error, stack empty");
                else {
                    StdOut.println("pop success:" + stack.pop() + " size:" + stack.size());
                    
                    StdOut.print("Left on stack: ");
                    for (String s : stack) {
                        StdOut.print(s + " ");
                    }
                    StdOut.println();
                }
            }
            
        }
        
    }
    
}

 

 

1.3.8

//1.3.8
package com.qiusongde;

import java.util.Iterator;
import java.util.NoSuchElementException;


import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class ResizingArrayStack<Item> implements Iterable<Item> {

    private Item[] content;
    private int number;
    
    public ResizingArrayStack() {
        content = (Item[]) new Object[1];
        number = 0;
    }
    
    private void resizeArray(int max) {
        
        if(max < number) 
            throw new IllegalArgumentException("the size of new array must larger than the size of Stack");
        
        Item[] temp = (Item[]) new Object[max];
        for(int i = 0; i < number; i++) {
            temp[i] = content[i];
        }
        content = temp;
    }
    
    
    public boolean isEmpty() {
        return number == 0;
    }
    
    public int size() {
        return number;
    }
    
    public void push(Item item) {
        
        if(number == content.length)
            resizeArray(2 * content.length);
        
        content[number++] = item;
    }
    
    public Item pop() {
        
        if(isEmpty())
            throw new NoSuchElementException("Stack is empty");
        
        Item item = content[--number];
        content[number] = null;//Aoid loitering
        
        if(number == content.length/4 && number > 0)
            resizeArray(content.length/2);
        
        return item;
    }

    @Override
    public Iterator<Item> iterator() {
        return new ReverseArrayIterator();
    }
    
    private class ReverseArrayIterator implements Iterator<Item> {

        private int i = number;
        
        @Override
        public boolean hasNext() {
            return i > 0;
        }

        @Override
        public Item next() {
            if(!hasNext())
                throw new NoSuchElementException("Stack is empty");
            return content[--i];
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }
    
    //Just for test(main)
    private int arrayLength() {
        return content.length;
    }
    
    public static void main(String[] args) {
        
        ResizingArrayStack<String> stack = new ResizingArrayStack<String>();
        StdOut.println("Initialized size:" + stack.size() + " Array Size:" + stack.arrayLength());
        
        while (!StdIn.isEmpty()) {
            
            String item = StdIn.readString();
            
            if (!item.equals("-")) {
                
                stack.push(item); 
                StdOut.println("push success:" + item + " size:" + stack.size() + " Array Size:" + stack.arrayLength());
                
                StdOut.print("Left on stack: ");
                for (String s : stack) {
                    StdOut.print(s + " ");
                }
                StdOut.println();
                
            } else {
                if(stack.isEmpty())
                    StdOut.println("pop error, stack empty");
                else {
                    StdOut.println("pop success:" + stack.pop() + " size:" + stack.size() + " Array Size:" + stack.arrayLength());
                    
                    StdOut.print("Left on stack: ");
                    for (String s : stack) {
                        StdOut.print(s + " ");
                    }
                    StdOut.println();
                }
            }
            
        }
        
    }
    
}
Initialized size:0 Array Size:1
it
push success:it size:1 Array Size:1
Left on stack: it 
was
push success:was size:2 Array Size:2
Left on stack: was it 
-
pop success:was size:1 Array Size:2
Left on stack: it 
the
push success:the size:2 Array Size:2
Left on stack: the it 
best
push success:best size:3 Array Size:4
Left on stack: best the it 
-
pop success:best size:2 Array Size:4
Left on stack: the it 
of
push success:of size:3 Array Size:4
Left on stack: of the it 
times
push success:times size:4 Array Size:4
Left on stack: times of the it 
-
pop success:times size:3 Array Size:4
Left on stack: of the it 
-
pop success:of size:2 Array Size:4
Left on stack: the it 
-
pop success:the size:1 Array Size:2
Left on stack: it 
it
push success:it size:2 Array Size:2
Left on stack: it it 
was
push success:was size:3 Array Size:4
Left on stack: was it it 
-
pop success:was size:2 Array Size:4
Left on stack: it it 
the
push success:the size:3 Array Size:4
Left on stack: the it it 
-
pop success:the size:2 Array Size:4
Left on stack: it it 
-
pop success:it size:1 Array Size:2
Left on stack: it 

 

1.3.9

主要思路:

用Dijkstra的双栈算法。

遇到数字则压入数字栈中(String)。

遇到运算符则压入运算符栈中(String)。

遇到右括号时,从数字栈和运算法栈中弹出相应的元素,生成相应的运算表达式(添加左括号)。

再次压入数字栈中(String)。

最后从数字栈中弹出最终的运算表达式。

//1.3.9
//only support +-*/ sqrt operator
package com.qiusongde;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class AddLeftParentheses {

    public static void main(String[] args) {
        
        Stack<String> ops = new Stack<String>();
        Stack<String> vals = new Stack<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            
            if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/") || s.equals("sqrt")) {
                ops.push(s);
            }
            else if(s.equals(")")) {
                String op = ops.pop();//operator
                String v = vals.pop();//value
                
                if(op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/")) {
                    String subexpression = "( " + vals.pop() + " " + op  + " " + v + " )";
                    vals.push(subexpression);
                }
                
                if(op.equals("sqrt")) {
                    String subexpression = op + " ( " + v + " )";
                    vals.push(subexpression);
                }
                
            }
            else {
                vals.push(s);
            }
            
        }
        
        StdOut.println(vals.pop());
        
    }

}

 

技术分享

 技术分享

技术分享

 

1.3.10

主要思路:和1.3.9相似,只不过运算表达式的生成方式不一样

用Dijkstra的双栈算法。

遇到数字则压入数字栈中(String)。

遇到运算符则压入运算符栈中(String)。

遇到右括号时,从数字栈和运算法栈中弹出相应的元素,生成相应的运算表达式(后缀表示)。

再次压入数字栈中(String)。

最后从数字栈中弹出最终的运算表达式。

 

//1.3.10
//only support +-*/ operator
package com.qiusongde;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class InfixToPostfix {
    
    
    public static void main(String[] args) {
        
        Stack<String> ops = new Stack<String>();
        Stack<String> vals = new Stack<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            
            if(s.equals("("))
                ;
            else if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
                ops.push(s);
            }
            else if(s.equals(")")) {
                
                String op = ops.pop();//operator
                String v = vals.pop();//value
                
                //only support +-*/ operator
                String subexpression = vals.pop() + " "  + v + " " + op;
                vals.push(subexpression);
                
            }
            else {
                vals.push(s);
            }
            
        }
        
        StdOut.println(vals.pop());
        
    }

}

 

技术分享

技术分享

 

1.3.11

主要思路:

这个和Dijkstrad的双栈算法不太一样,后缀的计算只需要一个栈即可。

用一个栈来存数字栈即可。

遇到数字,压栈。

遇到运算法,从栈中弹出相应的数字,用该运算法计算得到结果。

再次压入栈中。

最终从栈中弹出最终运算结果。

 

//1.3.11
//only support +-*/ operator
package com.qiusongde;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class EvaluatePostfix {

    public static void main(String[] args) {
        Stack<Double> vals = new Stack<Double>();
        
        while(!StdIn.isEmpty()) {
            
            String s = StdIn.readString();
            
            if(s.equals("+")) {
                double v = vals.pop();//second operand
                v = vals.pop() + v;
                vals.push(v);
            }
            else if(s.equals("-")) {
                double v = vals.pop();//second operand
                v = vals.pop() - v;
                vals.push(v);
            }
            else if(s.equals("*")) {
                double v = vals.pop();//second operand
                v = vals.pop() * v;
                vals.push(v);
            }
            else if(s.equals("/")) {
                double v = vals.pop();//second operand
                v = vals.pop() / v;
                vals.push(v);
            }
            else {
                vals.push(Double.parseDouble(s));
            }
            
        }
        
        StdOut.println(vals.pop());
        
    }

}

 

测试1:( 2 + ( ( 3 + 4 ) * ( 5 * 6 ) ) )

用Evaluate计算的结果:

技术分享

用InfixToPostfix转换结果:

 技术分享

用EvaluatePostfix计算的结果:

技术分享

 

测试2:( ( ( 6 + 2 ) * 5 ) - ( 8 / 4 ) )

 用Evaluate计算的结果:

 技术分享

用InfixToPostfix转换结果:

技术分享

用EvaluatePostfix计算的结果:

技术分享

 

1.3.12

package com.qiusongde;

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Stack<Item> implements Iterable<Item> {

    private Node first;
    private int n;
    
    private class Node {
        Item item;
        Node next;
    }
    
    //1.3.12
    public static Stack<String> copy(Stack<String> stack) {
        Stack<String> temp = new Stack<String>();
        Stack<String> result = new Stack<String>();
        
        for(String s : stack) {
            temp.push(s);
        }
        for(String s : temp) {
            result.push(s);
        }
            
        return result;
    }
    
    public Stack() {
        first = null;
        n = 0;
    }
    
    public void push(Item item) {
        Node oldfirst = first;
        
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        
        n++;
    }
    
    public Item pop() {
        
        if(isEmpty()) 
            throw new NoSuchElementException("Stack is empty");
        
        Item item = first.item;
        first = first.next;
        n--;
        
        return item;
    }
    
    //1.3.7
    public Item peek() {
        if(isEmpty())
            throw new NoSuchElementException("Stack is empty");
        
        return first.item;
    }
    
    public boolean isEmpty() {
        return first == null;
    }
    
    public int size() {
        return n;
    }

    @Override
    public Iterator<Item> iterator() {
        
        return new StackIterator();
    }
    
    private class StackIterator implements Iterator<Item> {

        private Node current = first;
        
        @Override
        public boolean hasNext() {
            return current != null;
        }

        @Override
        public Item next() {
            if(!hasNext())
                throw new NoSuchElementException("Stack is empty");
            
            Item item = current.item;
            current = current.next;
            
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Stack don‘t support remove");
        }
        
    }
    
    public static void main(String[] args) {
        
        Stack<String> stack = new Stack<String>();
        StdOut.println("Initialized size:" + stack.size());
        
        while (!StdIn.isEmpty()) {
            
            String item = StdIn.readString();
            
            if (!item.equals("-")) {
                
                stack.push(item); 
                StdOut.println("push success:" + item + " size:" + stack.size());
                
                StdOut.print("Left on stack: ");
                for (String s : stack) {
                    StdOut.print(s + " ");
                }
                StdOut.println();
                
            } else {
                if(stack.isEmpty())
                    StdOut.println("pop error, stack empty");
                else {
                    StdOut.println("pop success:" + stack.pop() + " size:" + stack.size());
                    
                    StdOut.print("Left on stack: ");
                    for (String s : stack) {
                        StdOut.print(s + " ");
                    }
                    StdOut.println();
                }
            }
            
        }
        
        //1.3.12
        Stack<String> copy = Stack.copy(stack);
        StdOut.println("copy stack:");
        for(String s : copy) {
            StdOut.print(s + " ");
        }
        StdOut.println();
        
    }
    
}
Initialized size:0
to
push success:to size:1
Left on stack: to 
be
push success:be size:2
Left on stack: be to 
or
push success:or size:3
Left on stack: or be to 
not
push success:not size:4
Left on stack: not or be to 
to
push success:to size:5
Left on stack: to not or be to 
copy stack:
to not or be to 

 

 

1.3.13

(a)  0 1 2 3 4 5 6 7 8 9

(b)  4 6 8 7 5 3 2 9 0 1 

(c)  2 5 6 7 4 8 9 3 1 0

(d)  4 3 2 1 0 5 6 7 8 9

答案:bcd

解释:因为Queue是先进先出的,而且加进队列是0-9按顺序添加的。

故任意位置上后边的数字都不能比该位置小。

(b)中3 2 0 1在4后边

(c)中1 0 在2后边

(d)中3 2 1 0 在4后边

 

1.3.14

//1.3.14
package com.qiusongde;

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class ResizingArrayQueue<Item> implements Iterable<Item> {
    
    private Item[] content;
    private int head;
    private int tail;
    private int n;
    
    public ResizingArrayQueue() {
        content = (Item[])new Object[1];
        n = head = tail = 0;
    }
    
    public int size() {
        return n;
    }
    
    public boolean isEmpty() {
        return n == 0;
    }
    
    private void resizeArray(int max) {
        
        if(max < n) 
            throw new IllegalArgumentException("the size of new array must larger than the size of Queue");
        
        Item[] temp = (Item[]) new Object[max];
        
        for(int i = 0; i < n; i++) {
            temp[i] = content[(head + i) % content.length];
        }
        head = 0;
        tail = n;
        content = temp;
    }
    
    public void enqueue(Item item) {
        
        if(n == content.length) {//full
            resizeArray(content.length * 2);//double array
        }
        
        content[tail++] = item;
        if(tail == content.length) {
            tail = 0;//wrap around
        }
        n++;
        
    }
    
    public Item dequeue() {
        
        if(isEmpty()) {//empty
            throw new NoSuchElementException("Queue is empty");
        }
        
        Item item = content[head];
        content[head] = null;//avoid loitering
        head++;//next
        if(head == content.length) {
            head = 0;//wrap around
        }
        n--;
        
        if(n == content.length/4 && n > 0) {
            resizeArray(content.length/2);
        }
        
        return item;
    }
    
    @Override
    public String toString() {
        String s;
        
        s = "Size:" + n +  " ArrayLength:" + content.length + " head:" + head + " tail:" + tail +"\\n";
        for(Item item : content) {
            s += item + " ";
        }
        s += "\\n";
        
        return s;
    }
    
    @Override
    public Iterator<Item> iterator() {
        return new ResizingArrayQueueIterator();
    }
    
    private class ResizingArrayQueueIterator implements Iterator<Item> {
        
        private int number = n;//initialize
        private int start = head;//initialize

        @Override
        public boolean hasNext() {
            return number > 0;
        }

        @Override
        public Item next() {
            
            if(!hasNext())
                throw new NoSuchElementException("Queue is empty");
            
            Item item = content[start++];
            if(start == content.length)
                start = 0;//wrap around
            number--;
            
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }

    public static void main(String[] args) {
        
        ResizingArrayQueue<String> queue = new ResizingArrayQueue<String>();
        StdOut.println(queue);
        
        while (!StdIn.isEmpty()) {
            
            String item = StdIn.readString();
            
            if (!item.equals("-")) {
                
                queue.enqueue(item);
                
                StdOut.println("enqueue success:" + item);
                StdOut.println(queue);
                
            } else {
                if(queue.isEmpty())
                    StdOut.println("dequeue error, stack empty");
                else {
                    
                    StdOut.println("dequeue success:" + queue.dequeue());
                    StdOut.println(queue);
                    
                }
            }
            
        }
        
        StdOut.println("Left in the ResizingArrayQueue:");
        for(String s : queue) {
            StdOut.print(s + " ");
        }
        StdOut.println();
        
    }

}

 

Size:0 ArrayLength:1 head:0 tail:0
null 

to
enqueue success:to
Size:1 ArrayLength:1 head:0 tail:0
to 

or
enqueue success:or
Size:2 ArrayLength:2 head:0 tail:0
to or 

not
enqueue success:not
Size:3 ArrayLength:4 head:0 tail:3
to or not null 

to
enqueue success:to
Size:4 ArrayLength:4 head:0 tail:0
to or not to 

be
enqueue success:be
Size:5 ArrayLength:8 head:0 tail:5
to or not to be null null null 

-
dequeue success:to
Size:4 ArrayLength:8 head:1 tail:5
null or not to be null null null 

-
dequeue success:or
Size:3 ArrayLength:8 head:2 tail:5
null null not to be null null null 

-
dequeue success:not
Size:2 ArrayLength:4 head:0 tail:2
to be null null 

-
dequeue success:to
Size:1 ArrayLength:2 head:0 tail:1
be null 

-
dequeue success:be
Size:0 ArrayLength:2 head:1 tail:1
null null 

to
enqueue success:to
Size:1 ArrayLength:2 head:1 tail:0
null to 

be
enqueue success:be
Size:2 ArrayLength:2 head:1 tail:1
be to 

Left in the ResizingArrayQueue:
to be 

 

1.3.15

package com.qiusongde;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1315 {

    public static void main(String[] args) {
        
        int k = Integer.parseInt(args[0]);
        Queue<String> queue = new Queue<>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            
            queue.enqueue(s);
        }
        
        int size = queue.size();
        for(int i = 0; i < size - k; i++) {
            queue.dequeue();
        }
        
        StdOut.println(queue.dequeue());
    }

}

 

1 2 3 4 5 6 7 8 9 10
6

 

1.3.16 1.3.17

 

1.3.18

Deletes from the list the node immediately following x.

 

1.3.19

package com.qiusongde.linkedlist;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedList<Item> implements Iterable<Item> {
    
    private Node first;
    
    private class Node {
        Item item;
        Node next;
    }
    
    public LinkedList() {
        first = null;
    }
    
    public void insertAtBeginning(Item item) {
        
        Node oldfirst = first;
        
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        
    }
    
    public Item removeFromBeginning() {
        
        if(isEmpty()) 
            throw new NoSuchElementException("LinkedList is empty");
        
        Item item = first.item;
        first = first.next;
        
        return item;
    }
    
    //1.3.19
    public Item removeTheLast() {
        
        Node precurrent = new Node();
        precurrent.next = first;
        Item item = null;
        
        //find the previous last node
        //precurrent.next is the same as current
        while(precurrent.next != null && precurrent.next.next != null) {
            precurrent = precurrent.next;
        }
        
        //has not found
        if(precurrent.next == null) {
            throw new NoSuchElementException("LinkedList is empty");
        }
        
        item = precurrent.next.item;
        //some implementation will add one empty node as head, and head.next = first
        //if so, it‘s not necessary to have if condition here
        if(precurrent.next == first)
            first = precurrent.next.next;
        else
            precurrent.next = precurrent.next.next;
        
        return item;    
    }
    
    public boolean isEmpty() {
        return first == null;
    }
    
    public String toString() {
        String s = "";
        
        Node temp = first;
        
        while(temp != null) {
            Item item = temp.item;
            s += item + " ";
            temp = temp.next;
        }
        
        return s;
    }

    @Override
    public Iterator<Item> iterator() {
        return new ListIterator();
    }
    
    private class ListIterator implements Iterator<Item> {
        
        private Node current = first;

        @Override
        public boolean hasNext() {
            return current != null;
        }

        @Override
        public Item next() {
            if(!hasNext())
                throw new NoSuchElementException();
            
            Item item = current.item;
            current = current.next;
            
            return item;
        }
        
        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }
    
}

 

 

package com.qiusongde.linkedlist;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1319 {

    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            list.insertAtBeginning(s);
            StdOut.println("insertAtBeginning success: " + s);
            StdOut.println(list);
        }
        
        String s = list.removeTheLast();
        StdOut.println("removeTheLast success: " + s);
        StdOut.println(list);
        
    }

}

测试数据1:

to
be
or
not
to
be

 

结果:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
insertAtBeginning success: be
be to not or be to 
removeTheLast success: to
be to not or be 

 

测试数据2:

to

 

结果:

insertAtBeginning success: to
to 
removeTheLast success: to

 

测试数据3:

输入为空

 

结果:

Exception in thread "main" java.util.NoSuchElementException: LinkedList is empty
    at com.qiusongde.linkedlist.LinkedList.removeTheLast(LinkedList.java:45)
    at com.qiusongde.linkedlist.Exercise1319.main(Exercise1319.java:18)

 

1.3.20

在LinkedList类添加以下方法:

  //1.3.20
    public Item delete(int k) {
        
        if(k < 1)
            throw new IllegalArgumentException("k must larger than 1");
        
        Node precurrent = new Node();
        precurrent.next = first;
        Item item;
        
        while(precurrent.next != null && k > 1) {
            precurrent = precurrent.next;
            k--;
        }
        
        if(precurrent.next == null) 
            throw new NoSuchElementException("LinkedList hasn‘t so many elements");
        
        item = precurrent.next.item;
        if(precurrent.next == first)
            first = precurrent.next.next;
        else
            precurrent.next = precurrent.next.next;
        
        return item;
    }

 

package com.qiusongde.linkedlist;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1320 {

    public static void main(String[] args) {
        
        LinkedList<String> list = new LinkedList<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            list.insertAtBeginning(s);
            StdOut.println("insertAtBeginning success: " + s);
            StdOut.println(list);
        }
        
        int k = 5;
        String s = list.delete(k);
        StdOut.println("delete " + k + "th Element success: "+ s);
        StdOut.println(list);
        
        for(int i = 0; i < 4; i++) {
            k = 1;
            s = list.delete(k);
            StdOut.println("delete " + k + "th Element success: "+ s);
            StdOut.println(list);
        }
        
        k = 5;
        s = list.delete(k);
        StdOut.println("delete " + k + "th Element success: "+ s);
        StdOut.println(list);
    }

}

 

测试数据:

to
be
or
not
to

 

结果:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
delete 5th Element success: to
to not or be 
delete 1th Element success: to
not or be 
delete 1th Element success: not
or be 
delete 1th Element success: or
be 
delete 1th Element success: be

Exception in thread "main" java.util.NoSuchElementException: LinkedList hasn‘t so many elements
    at com.qiusongde.linkedlist.LinkedList.delete(LinkedList.java:84)
    at com.qiusongde.linkedlist.Exercise1320.main(Exercise1320.java:32)

 

 

1.3.21

在LinkedList类添加以下方法:

//1.3.21
    public boolean find(LinkedList<String> list, String key) {
        
        for(String s : list) {
            if(s.equals(key))
                return true;
        }
        
        return false;
    }

 

测试用例:

package com.qiusongde.linkedlist;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1321 {

    public static void main(String[] args) {
        
        LinkedList<String> list = new LinkedList<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            list.insertAtBeginning(s);
            StdOut.println("insertAtBeginning success: " + s);
            StdOut.println(list);
        }
        
        String key = "qiu";
        StdOut.println("find " + key + " :" + list.find(list, key));
        
        key = "not";
        StdOut.println("find " + key + " :" + list.find(list, key));
        
    }
    
}

 

输入数据:

to
be
or
not
to

 

输出结果:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
find qiu :false
find not :true

 

 

1.3.22

Insert node t immediately after node x

 

1.3.23

When it comes time to update t.next, x.next is no longer the original node following x, but is instead of itself!

 

1.3.24 1.3.25

实现过程中,Node未内部类,用private修饰,不能再外边访问。

所以这两个函数没有意义。

 

1.3.26

测试用例:

package com.qiusongde.linkedlist;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1326 {

    public static void main(String[] args) {
        
        String key = "qiu";
        
        LinkedList<String> list = new LinkedList<String>();
        
        while(!StdIn.isEmpty()) {
            String s = StdIn.readString();
            list.insertAtBeginning(s);
            StdOut.println("insertAtBeginning success: " + s);
            StdOut.println(list);
        }
        
        list.remove(list, key);
        StdOut.println("remove success:" + key);
        StdOut.println(list);
        
    }

}

 方法实现:

  //1.3.26
    /*
     * remove all of the nodes in the list that have key as its item field
     * 
     * @param list the linked list
     * @param key the key
     * 
     * @return void
     * 
     */
    public void remove(LinkedList<String> list, String key) {
        Node precurrent;
        precurrent = findPreNode(key);
        
        //remove all of the nodes
        while(precurrent.next != null) {
            
            if(precurrent.next == first)
                first = first.next;
            else
                precurrent.next = precurrent.next.next;
            
            precurrent = findPreNode(key);
        }
        
    }
    
    //1.3.26
    /*
     * find the node in the list whose item equals key
     * 
     * @param key the key
     * 
     * @return return the previous node whose item equals key
     */
    private Node findPreNode(String key) {
        Node precurrent = new Node();
        precurrent.next = first;
        
        while(precurrent.next != null && !precurrent.next.item.equals(key)) {
            precurrent = precurrent.next;
        }
        
        return precurrent;
    }

输入数据:

to
be
or
not
to

 

输出结果1:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
remove success:to
not or be 

 输出结果2:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
remove success:not
to or be to 

 输出结果3:

insertAtBeginning success: to
to 
insertAtBeginning success: be
be to 
insertAtBeginning success: or
or be to 
insertAtBeginning success: not
not or be to 
insertAtBeginning success: to
to not or be to 
remove success:qiu
to not or be to 

 

1.3.27 1.3.28

方法实现:

    //1.3.27
    /*
     * return the value of the maximum key in the list
     * 
     * @param list the linked list of Integer
     * 
     * @return return the maximum key in the list
     */
    public static int max(LinkedList<Integer> list) {
        
        if(list.first == null)
            return 0;
        
        int max = 0;
        for(int val : list) {
            if(val > max)
                max = val;
        }
        
        return max;
    }
    
    //1.3.28
    /*
     * return the value of the maximum key in the list by recursion
     * 
     * @param list the linked list of Integer
     * 
     * @return return the maximum key in the list
     */
    public static int maxByRecursion(LinkedList<Integer> list) {
        
        if(list.first == null)
            return 0;
        
        int first = list.first.item;//first item
        list.first = list.first.next;//remove first item in the list
        int max = maxByRecursion(list);//calculate the maximum value of the new list
        
        if(first > max)
            return first;
        else
            return max;
    }

测试用例:

package com.qiusongde.linkedlist;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class Exercise1327 {

    public static void main(String[] args) {
        
        LinkedList<Integer> list = new LinkedList<Integer>();
        
        while(!StdIn.isEmpty()) {
            int val = StdIn.readInt();
            list.insertAtBeginning(val);
            StdOut.println("insertAtBeginning success: " + val);
            StdOut.println(list);
        }
        
        int max = LinkedList.max(list);
        StdOut.println("The maximum key is:" + max);
        
        max = LinkedList.maxByRecursion(list);
        StdOut.println("The maximum key is:" + max + "(By Recursion)");
    }

}

 

测试数据1:

insertAtBeginning success: 90
90 
insertAtBeginning success: 78
78 90 
insertAtBeginning success: 32
32 78 90 
insertAtBeginning success: 6
6 32 78 90 
insertAtBeginning success: 69
69 6 32 78 90 
insertAtBeginning success: 26
26 69 6 32 78 90 
insertAtBeginning success: 51
51 26 69 6 32 78 90 
insertAtBeginning success: 100
100 51 26 69 6 32 78 90 
insertAtBeginning success: 30
30 100 51 26 69 6 32 78 90 
insertAtBeginning success: 25
25 30 100 51 26 69 6 32 78 90 
insertAtBeginning success: 10
10 25 30 100 51 26 69 6 32 78 90 
The maximum key is:100
The maximum key is:100(By Recursion)

 

测试数据2:

insertAtBeginning success: 90
90 
insertAtBeginning success: 78
78 90 
The maximum key is:90
The maximum key is:90(By Recursion)

 

测试数据3:

insertAtBeginning success: 90
90 
The maximum key is:90
The maximum key is:90(By Recursion)

 

测试数据4:(输入为空)

The maximum key is:0
The maximum key is:0(By Recursion)

 

1.3.29

代码实现:

//1.3.29
package com.qiusongde.linkedlist;

import java.util.Iterator;
import java.util.NoSuchElementException;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class CircularQueue<Item> implements Iterable<Item> {

    private Node last;
    private int n;
    
    private class Node {
        Item item;
        Node next;
    }
    
    public CircularQueue() {
        last = null;
        n = 0;
    }
    
    public boolean isEmpty() {
        return last == null;
    }
    
    public int size() {
        return n;
    }
    
    public void enqueue(Item item) {
        
        Node oldlast = last;//save oldlast
        
        last = new Node();//new node
        last.item = item;
        if(oldlast == null) {//empty
            last.next = last;
        }
        else {
            last.next = oldlast.next;//next is first
            oldlast.next = last;
        }
        
        n++;
    }
    
    public Item dequeue() {
        if(isEmpty())
            throw new NoSuchElementException("Queue is empty");
        
        Item item = last.next.item;
        
        if(last.next == last) {//only one node
            last = null;
        } else {
            last.next = last.next.next;
        }
        
        n--;
                
        return item;
    }

    @Override
    public Iterator<Item> iterator() {
        return new CircularQueueIterator();
    }
    
    private class CircularQueueIterator implements Iterator<Item> {

        //it is important that this class cannot change the CircularQueue
        //so we can only change precurrent and can‘t change precurrent.next
        private Node precurrent;
        
        public CircularQueueIterator() {
            precurrent = last;
        }
        
        @Override
        public boolean hasNext() {
            return precurrent != null;
        }

        @Override
        public Item next() {
            if(!hasNext())
                throw new NoSuchElementException("Queue is empty");
            
            Item item = precurrent.next.item;
            
            if(last == last.next) {//one node
                precurrent = null;//end
            } else {
                precurrent = precurrent.next;
                if(precurrent == last) {//precurrent equals last again
                    precurrent = null;//end
                }
            }
                
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
        
    }
    
    public static void main(String[] args) {
        
        CircularQueue<String> queue = new CircularQueue<String>();
        StdOut.println("Initialized size:" + queue.size());
        
        while (!StdIn.isEmpty()) {
            
            String item = StdIn.readString();
            
            if (!item.equals("-")) {
                
                queue.enqueue(item); 
                StdOut.println("enqueue success:" + item + " size:" + queue.size());
                
                StdOut.print("Left on queue: ");
                for (String s : queue) {
                    StdOut.print(s + " ");
                }
                StdOut.println();
                
            } else {
                if(queue.isEmpty())
                    StdOut.println("dequeue error, queue empty");
                else {
                    StdOut.println("dequeue success:" + queue.dequeue() + " size:" + queue.size());
                    
                    StdOut.print("Left on queue: ");
                    for (String s : queue) {
                        StdOut.print(s + " ");
                    }
                    StdOut.println();
                }
            }
            
        }
        
    }

}

 

测试数据:

to
be
or
not
to
-
be
-
-
that
-
-
-
is

 

输出结果:

Initialized size:0
enqueue success:to size:1
Left on queue: to 
enqueue success:be size:2
Left on queue: to be 
enqueue success:or size:3
Left on queue: to be or 
enqueue success:not size:4
Left on queue: to be or not 
enqueue success:to size:5
Left on queue: to be or not to 
dequeue success:to size:4
Left on queue: be or not to 
enqueue success:be size:5
Left on queue: be or not to be 
dequeue success:be size:4
Left on queue: or not to be 
dequeue success:or size:3
Left on queue: not to be 
enqueue success:that size:4
Left on queue: not to be that 
dequeue success:not size:3
Left on queue: to be that 
dequeue success:to size:2
Left on queue: be that 
dequeue success:be size:1
Left on queue: that 
enqueue success:is size:2
Left on queue: that is 

 




以上是关于1.3 Bags, Queues, and Stacks(算法 Algorithms 第4版)的主要内容,如果未能解决你的问题,请参考以下文章

A. Dawid and Bags of Candies ( Codeforces Round #588 (Div. 2) )

Codechef APRIL14 ANUCBC Cards, bags and coins 题解

Dispatch Queues and Thread Safety

Tasks, microtasks, queues and schedules

Tasks, microtasks, queues and schedules

5.15 - Stacks and Queues