算法(第四版)Java 第一章1.3节 题解

本书提供Java版《算法》题解,包括题解代码、依赖库访问和交流方式。涵盖多种数据结构与算法题型,如栈的操作、链表处理、队列实现等。此外,还提供了迭代器、链表、队列、环形队列、堆栈等数据结构的实现案例。代码示例丰富,适合学习和实践。

前言

整本《算法》Java版的题解已经托管在Github上:https://github.com/Mereder/Algorithms_4th ,大家根据README.md的导航可以迅速定位章节。

书中代码用到了很多《算法》官方提供的依赖:https://algs4.cs.princeton.edu/home/  大家可以去官网多逛逛,图书章节配合官网内容一起看效果很好。

欢迎大家站内私聊交流!小白一枚,还请前辈们多多指教!

本部分内容全部以代码形式展示,编译器为IDEA 2018版,Java版本为1.8.0_151,系统为Windows7 。

内容(1.3节)

1.3.1

/**
 * 为FixedCapacityStackOfStrings 添加一个方法 isFull();
 */
public class E_01 {
    public static class FixedCapacityStackOfStrings{
        private String[] a;
        private int N;
        public FixedCapacityStackOfStrings(int cap){
            a = new String[cap];
        }
        public boolean isEmpty(){
            return N == 0;
        }
        public boolean isFull(){
            return N == a.length;
        }
        public int size(){
            return N;
        }
        public void push(String item){
            a[N++] = item;
        }
        public String pop(){
            return a[--N];
        }
    }

    public static void main(String[] args) {
        FixedCapacityStackOfStrings fixedCapacityStackOfStrings = new FixedCapacityStackOfStrings(3);
        fixedCapacityStackOfStrings.push("hello");
        fixedCapacityStackOfStrings.push("java");
        fixedCapacityStackOfStrings.push("hello");
        if (fixedCapacityStackOfStrings.isFull()) System.out.println("full");
        else fixedCapacityStackOfStrings.push("world");
    }
}

1.3.2

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

/**
 * 给定以下输入,java Stack 的输出是什么?
 * it was - the best - of times - - - it was - the - -
 * Result:
 * was best times of the was the it
 */
public class E_02 {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<String>();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            if (!item.equals("-"))
                stack.push(item);
            else if (!stack.isEmpty())
                StdOut.print(stack.pop() + " ");
        }
        StdOut.println("(" + stack.size() + " 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
 *
 * b f g 是不可能的
 */
public class E_03 {
}

1.3.4

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.StdOut;

/**
 * 编写一个Stack的用例parentheses,从标准输入中读取一个文本流并使用栈判定其中的括号是否配对完整
 * 例如 [()]{}{[()()]()} 打印true
 * [(])打印 false
 */
public class E_04 {
    public static 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  boolean isBalanced(String s) {
            Stack<Character> stack = new Stack<Character>();
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) == LEFT_PAREN)   stack.push(LEFT_PAREN);
                if (s.charAt(i) == LEFT_BRACE)   stack.push(LEFT_BRACE);
                if (s.charAt(i) == LEFT_BRACKET) stack.push(LEFT_BRACKET);

                if (s.charAt(i) == RIGHT_PAREN) {
                    if (stack.isEmpty())           return false;
                    if (stack.pop() != LEFT_PAREN) return false;
                }

                else if (s.charAt(i) == RIGHT_BRACE) {
                    if (stack.isEmpty())           return false;
                    if (stack.pop() != LEFT_BRACE) return false;
                }

                else if (s.charAt(i) == RIGHT_BRACKET) {
                    if (stack.isEmpty())             return false;
                    if (stack.pop() != LEFT_BRACKET) return false;
                }
            }
            return stack.isEmpty();
        }
    }
    public static void main(String[] args) {
        Parentheses parentheses = new Parentheses();
        In in = new In();
        String s = in.readAll().trim();
        StdOut.println(parentheses.isBalanced(s));
    }
}

1.3.5

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

/**
 * 当N等于50 时 下面这段代码会打印出什么?从较高抽象层次描述给定正整数N时这段代码的行为。
 * Result:
 * 当N=50时,打印 110010
 * 抽象层次描述:打印N的二进制
 */
public class E_05 {

    public static void main(String[] args) {
        int N = StdIn.readInt();
        Stack<Integer> stack = new Stack<Integer>();
        while (N > 0){
            stack.push(N % 2);
            N = N / 2;
        }
        for (int d : stack) {
            System.out.print(d);
        }
        System.out.println();
    }
}

1.3.6

import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.Stack;

/**
 * 下面这段代码对队列q进行了什么操作?
 * 借助一个栈 将队列q逆序
 */
public class E_06 {
    public static void main(String[] args) {
        Queue<String> q = new Queue<>();
        Stack<String> stack = new Stack<>();
        while(!q.isEmpty())
            stack.push(q.dequeue());
        while (!stack.isEmpty())
            q.enqueue(stack.pop());
    }
}

1.3.7

/**
 * 为Stack 添加一个方法peek() 返回栈中最近添加的元素(而不弹出)。
 * 参考Stack类
 * 注意 先判断是否非空  非空则返回栈顶 否则 丢错
 */
public class E_07 {
}

1.3.8

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

/**
 * 给定以下输入,给出DoublingStackOfStrings 的数组的内容和大小。
 * doublingstackofstrings 应该是那个可以动态调整数组大小的栈的实现形式
 * it was - the best - of times - - - it was - the - -
 * output:was best times of the was the it ^D
 * (1 left on stack)
 *   it
 *   大小为:2
 *
 *   数组内容仅剩下一个it 大小 次数数组大小为 2
 */
public class E_08 {
    public static class DoublingStackOfStrings{
        private String[] a = new String[1];
        private int N = 0;

        public boolean isEmpty(){ return N == 0; }
        public int size(){
            return N;
        }
        public int Arraysize(){return a.length; }
        private void resize(int max){
            String[] temp = new String[max];
            for (int i = 0; i < N; i++) {
                temp[i] = a[i];
            }
            a = temp;
        }
        public void push(String item){
            if (N == a.length) resize(2 * a.length);
            a[N++] = item;
        }
        public String pop(){
            String string = a[--N];
            a[N] = null;
            if (N > 0 && N == a.length/4)
                resize(a.length/2);
            return string;
        }

        @Override
        public String toString() {
            String string = " ";
            for (int i = 0; i < N; i++) {
                string += " "+a[i];
            }
            return string;
        }
    }

    public static void main(String[] args) {
        DoublingStackOfStrings stack = new DoublingStackOfStrings();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            if (!item.equals("-"))
                stack.push(item);
            else if (!stack.isEmpty())
                StdOut.print(stack.pop() + " ");
        }
        StdOut.println("(" + stack.size() + " left on stack)");
        System.out.println(stack);
        System.out.println("大小为:"+stack.Arraysize());
    }
}

1.3.9

package com.mereder.Algs_Exercise.Exercises1_3;

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

/**
 * 编写一段程序从标准输入得到一个缺少左括号的表达式并打印出补全括号之后的中序表达式。
 * 例如:1 + 2 ) * 3 - 4 ) * 5 - 6 ) ) )
 */
public class E_09 {
    public static String FillLeftparentheses(String string){
        Stack<String> opsstack = new Stack<>();
        Stack<String> datastack = new Stack<>();

        int N = string.length();
        for (int i = 0; i < N; i++) {
            char ch = string.charAt(i);
            if (Character.isSpaceChar(ch) ) continue;
            if (Character.isDigit(ch)) datastack.push(Character.toString(ch));
            else if ("*+-/".contains(Character.toString(ch))) opsstack.push(Character.toString(ch));

            else if (ch == ')'){
                String data2 = datastack.pop();
                String data1 = datastack.pop();
                String op = opsstack.pop();
                String expression = "("+data1+op+data2+")";
                datastack.push(expression);
            }
        }

        return datastack.pop();
    }
    public static void main(String[] args) {
        String input = StdIn.readLine();
        System.out.println(input);
        String output = FillLeftparentheses(input);
        System.out.println(output);
    }
}

1.3.10

package com.mereder.Algs_Exercise.Exercises1_3;

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

/**
 * 编写一个过滤器InfixToPostfix,将算术表达式由中序表达式变为后序表达式
 * 处理情况 均需要使用parentheses 括起来的 ((1+2)*((3-4)*(5-6)))
 * 不能很好的处理 1+2*3这种。
 */
public class E_10 {
    public static String InfixToPostfix(String infix){
        Stack<Character> opstack = new Stack<>();
        String postfix = "";
        int N = infix.length();
        for (int i = 0; i < N; i++) {
            char ch = infix.charAt(i);
            if (ch == ' ' || ch == '(') continue;
            else if (Character.isDigit(ch)) postfix += ch;
            else if ("*+/-".contains(String.valueOf(ch))) opstack.push(ch);
            else if (ch == ')'){
                postfix += opstack.pop();
            }
        }
        return postfix;
    }
    public static void main(String[] args) {
        String input = StdIn.readLine();
        System.out.println(input);
        String output = InfixToPostfix(input);
        System.out.println(output);
    }
}

1.3.11

import edu.princeton.cs.algs4.Stack;

/**
 * 编写一段程序EvaluatePostFix 从标准输入中得到一个后序表达式,求值并打印结果
 * 将第10题中的输出用管道传递给这一段程序可以得到和Evaluate相同的行为
 */
public class E_11 {
    public static int EvaluatePostfix(String postfix){
        Stack<Integer> datastack = new Stack<>();
        int N = postfix.length();
        for (int i = 0; i < N; i++) {
            char ch = postfix.charAt(i);

            if (ch == '+'){
                datastack.push(datastack.pop()+datastack.pop());
            }
            else if(ch == '-'){
                int data1 = datastack.pop();
                datastack.push(datastack.pop()-data1);
            }
            else if (ch == '*'){
                datastack.push(datastack.pop()*datastack.pop());
            }
            else if (ch == '/'){
                int data1 = datastack.pop();
                datastack.push(datastack.pop()-data1);
            }
            else if (Character.isDigit(ch)) datastack.push(Character.getNumericValue(ch));

        }
        return datastack.pop();
    }
    public static void main(String[] args) {
        String input = "12+34-56-**";
        int result = EvaluatePostfix(input);
        System.out.println(result);

    }
}

1.3.12

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

/** E_12题 (拿题号做类名是在太难受了)
 * 编写一个可迭代的Stack用例,它含有一个静态的copy方法,接受一个字符串的栈作为参数
 * 返回该栈的一个副本。
 * @param <Item>
 */
public class IterableStack<Item> implements Iterable<Item> {
        private Node<Item> first;     // top of stack
        private int n;                // size of the stack

        // helper linked list class
        private  class Node<Item> {
            private Item item;
            private Node<Item> next;
        }

        /**
         * Initializes an empty stack.
         */
        public IterableStack() {
            first = null;
            n = 0;
        }

        /**
         * Returns true if this stack is empty.
         *
         * @return true if this stack is empty; false otherwise
         */
        public boolean isEmpty() {
            return first == null;
        }

        /**
         * Returns the number of items in this stack.
         *
         * @return the number of items in this stack
         */
        public int size() {
            return n;
        }

        /**
         * Adds the item to this stack.
         *
         * @param  item the item to add
         */
        public void push(Item item) {
            Node<Item> oldfirst = first;
            first = new Node<Item>();
            first.item = item;
            first.next = oldfirst;
            n++;
        }

        /**
         * Removes and returns the item most recently added to this stack.
         *
         * @return the item most recently added
         * @throws NoSuchElementException if this stack is empty
         */
        public Item pop() {
            if (isEmpty())
                throw new NoSuchElementException("Stack underflow");
            Item item = first.item;        // save item to return
            first = first.next;            // delete first node
            n--;
            return item;                   // return the saved item
        }

        /**
         * Returns (but does not remove) the item most recently added to this stack.
         *
         * @return the item most recently added to this stack
         * @throws NoSuchElementException if this stack is empty
         */
        public Item peek() {
            if (isEmpty()) throw new NoSuchElementException("Stack underflow");
            return first.item;
        }

        public static IterableStack<String> copy(IterableStack<String> IterableStackString){
            IterableStack<String> temp = new IterableStack<>();
            IterableStack<String> result = new IterableStack<>();

            for (String s:IterableStackString){
                temp.push(s);
            }
            for (String s : temp) {
                result.push(s);
            }
            return result;
        }
        /**
         * Returns a string representation of this stack.
         *
         * @return the sequence of items in this stack in LIFO order, separated by spaces
         */
        public String toString() {
            StringBuilder s = new StringBuilder();
            for (Item item : this) {
                s.append(item);
                s.append(' ');
            }
            return s.toString();
        }

        /**
         * Returns an iterator to this stack that iterates through the items in LIFO order.
         *
         * @return an iterator to this stack that iterates through the items in LIFO order
         */
        public Iterator<Item> iterator() {
            return new ListIterator<Item>(first);
        }

        // an iterator, doesn't implement remove() since it's optional
        private class ListIterator<Item> implements Iterator<Item> {
            private Node<Item> current;

            public ListIterator(Node<Item> first) {
                current = first;
            }

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

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

            public Item next() {
                if (!hasNext()) throw new NoSuchElementException();
                Item item = current.item;
                current = current.next;
                return item;
            }
        }

    public static void main(String[] args) {
        IterableStack<String> stack = new IterableStack<>();
        stack.push("hello");
        stack.push("world");
        stack.push("hello");
        stack.push("java");
        IterableStack<String> newstack = new IterableStack<>();
        newstack = copy(stack);
        for (String ss : newstack) {
            System.out.println(ss);
        }
    }

}

 

1.3.13

/**
 * 假设某个用例程序会进入一系列入列和出列的混合操作,入列操作会将整数0到9按顺序插入队列
 * 出列操作会打印出返回值。下面哪种序列是不可能产生的
 *
 * Anwser:队列顺序先进先出  0-》9进队列
 * 只能 0-9 出队列
 * b c d 均不可能
 */
public class E_13 {
}

1.3.14

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

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

/**
 * 编写一个ResizingArrayQueueOfStrings类,使用定长数组实现队列的抽象,然后扩展实现,使用
 * 调整数组的方法突破大小的限制
 */
public class ResizingArrayQueueOfStrings {
    private String[] Queue;
    private int N ;
    private int first;  //第一个元素
    private int last;  // 最后一个元素的下一个

    public ResizingArrayQueueOfStrings() {
        Queue = new String[1];
        N = 0;
        first = 0;
        last = 0;
    }

    public String[] getString() {
        return Queue;
    }
    public int size() {
        return N;
    }
    public int getFirst() {
        return first;
    }
    public int getLast() {
        return last;
    }

    public boolean isEmpty(){
        return N == 0;
    }
    public String Dequeue(){
        if (isEmpty()) throw new NoSuchElementException("No data");
        else {
            N--;
            String item = Queue[first];
            Queue[first] = null;
            first++;
            if (first == Queue.length) first = 0;
            if (N > 0 && N == Queue.length/4) Resizing(Queue.length/2);
            return item;
        }
    }
    public void Enqueue(String item){
        if (N == Queue.length) Resizing(2*Queue.length);
        Queue[last++] = item;
        if (last == Queue.length) last = 0;
        N++;
    }
    public String peek() {
        if (isEmpty()) throw new NoSuchElementException("Queue underflow");
        return Queue[first];
    }

    public void Resizing(int max){
        String[] strings = new String[max];
        for (int i = 0; i < N; i++) {
            strings[i] = Queue[(first + i) % Queue.length ]; // first+i 可能越界 取余
        }
        Queue = strings;
        first = 0;
        last = N;
    }

    //实现迭代
    public Iterator<String> iterator(){
        return new ArrayIterator();
    }

    public class ArrayIterator implements Iterator<String>{
        private int i = 0;
        @Override
        public boolean hasNext() {
            return i < N;
        }

        @Override
        public String next() {
            if (!hasNext()) throw new NoSuchElementException();
            String string = Queue[(first+i) % Queue.length];
            i++;
            return string;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    public static void main(String[] args) {
        ResizingArrayQueueOfStrings queue = new ResizingArrayQueueOfStrings();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            if (!item.equals("-")) queue.Enqueue(item);
            else if (!queue.isEmpty()) StdOut.print(queue.Dequeue() + " ");
        }
        StdOut.println("(" + queue.size() + " left on queue)");
    }
}

1.3.15

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

import java.util.NoSuchElementException;


/**
 * 编写一个Queue的用例,接受一个命令行参数k 并打印出标准输入中的倒数第k个字符串
 */
public class E_15 {
    public static Queue<String> queue = new Queue<>();
    public static String count_backwards_K(int k){
        int N = queue.size();
        if (k > N) throw new NoSuchElementException();
        String result;
        for (int i = 0; i <  N - k; i++) {
            queue.dequeue();
        }
        result = queue.dequeue();
        return result;
    }
    public static void main(String[] args) {
        System.out.println("输入参数 k :");
        int K = StdIn.readInt();

        System.out.println("输入大于k个字符串:");
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            queue.enqueue(item);
        }
        String result = count_backwards_K(K);
        System.out.println(result);

    }
}

1.3.16

import edu.princeton.cs.algs4.Date;
import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdIn;

/**
 * 使用1.3.1.5节中的readInts()作为模板为Date 编写一个静态方法ReadDates(),
 * 从标准输入中读取由练习1.2.19的表格所指定的格式的多个日期并返回一个它们的数组
 * 命令行 中断输入  ctrl + d
 */
public class E_16 {
    public static Date[] readDates(){
        Queue<Date> queue = new Queue<>();
        while(!StdIn.isEmpty()) queue.enqueue(new Date(StdIn.readString()));

        int N = queue.size();
        Date[] dates = new Date[N];
        for (int i = 0; i < N; i++) {
            dates[i] = queue.dequeue();
        }
        return dates;
    }
    public static void main(String[] args) {
        Date[] dates = readDates();
        for (int i = 0; i < dates.length; i++) {
            System.out.println(dates[i]);
        }
    }
}

1.3.17

import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.Transaction;

/**
 * 使用1.3.1.5节中的readInts()作为模板为Transaction 编写一个静态方法ReadTransactions(),
 * 从标准输入中读取由练习1.2.19的表格所指定的格式的多个日期并返回一个它们的数组
 * 均需要从命令行 中断输入  ctrl + d
 */
//truning 2/22/2222 22.22
public class E_17 {
    public static Transaction[] readTransaction(){
        Queue<Transaction> queue = new Queue<>();
        while(!StdIn.isEmpty()) queue.enqueue(new Transaction(StdIn.readLine() ));

        int N = queue.size();
        Transaction[] transactions = new Transaction[N];
        for (int i = 0; i < N; i++) {
            transactions[i] = queue.dequeue();
        }
        return transactions;
    }
    public static void main(String[] args) {
        Transaction[] transactions = readTransaction();
        for (int i = 0; i < transactions.length; i++) {
            System.out.println(transactions[i]);
        }
    }
}

1.3.18

/**
 * 假设x是一条链表的某个结点而不是尾结点,下面这条语句的效果是什么?
 * x.next= x.next.next
 * 1 2 3 4 5
 * x 为 3
 * x.next 为 4
 * x.next.next 为5
 * x.next= x.next.next
 * 链表变为 1 2 3 5
 */
public class E_18 {
    public static class Node{
        public int item;
        public Node next;
    }

    public static void main(String[] args) {
        Node first = new Node();
        first.item = 1;
        Node second = new Node();
        second.item = 2;
        Node third = new Node();
        third.item = 3;

        first.next = second;
        second.next = third;
        third.next = null;

        //x.next= x.next.next
        first.next = first.next.next;

        while (first != null){
            System.out.println(first.item);
            first = first.next;
        }
        // 结果为
        // 1
        // 3

    }
}

1.3.19

import edu.princeton.cs.algs4.StdRandom;

/**
 * 给出一段代码,其中链表的首节点为first 删除链表的尾结点。
 */
public class E_19 {
    public Node first;
    public int n;

    public static class Node{
        public int item;
        public Node next;
    }

    public E_19() {
        first = null;
        n = 0;
    }
    public void append(int item) {
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        n++;
    }
    public void DeleteLast(){
        Node current = first;

        while(current.next.next != null){
            current = current.next;
        }
        current.next = current.next.next;
        n--;
    }

    public static void main(String[] args) {
        E_19 Linklist = new E_19();

        for (int i = 0; i < 5; i++) {
            Linklist.append(StdRandom.uniform(1,20));
        }
        Linklist.DeleteLast();
        System.out.println(Linklist.n);
    }
}

1.3.20

import java.util.NoSuchElementException;

/**
 * 编写一个方法delete() 接受一个参数K,删除链表的第K个元素
 */
public class E_20 {
    private int n;
    private Node first;

    public E_20(){
        n = 0;
        first = null;
    }
    //链表的每个节点类
    private static class Node{
        private String item;
        private Node next;


    }
    public void append(String item) {
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        n++;
    }

    public void delete(int K){
        if (K > n) throw new NoSuchElementException("less than k");
        else if (K <= 0) throw new NoSuchElementException("error K");
        else{
            Node current;
            Node previous;
            current = first;
            previous = first;

            if (K == 1){
                System.out.println("删除元素为:"+first.item);
                first = first.next;
                n--;
            }
            else {
                while(K-1 > 0 ){
                    previous = current;
                    current = current.next;
                    K--;
                }
                System.out.println("删除元素为:"+current.item);
                previous.next = current.next;
                n--;
            }
        }
    }
    public void display(){
        if(n >0){
            Node node = first;
            int tempSize = n;
            if(tempSize == 1){//当前链表只有一个节点
                System.out.println("["+node.item+"]");
                return;
            }
            while(tempSize > 0){
                if(node.equals(first)){
                    System.out.print("["+node.item+"->");
                }else if(node.next == null){
                    System.out.print(node.item+"]");
                }else{
                    System.out.print(node.item+"->");
                }
                node = node.next;
                tempSize--;
            }
            System.out.println();
        }
        //如果链表一个节点都没有,直接打印[]
        else{
            System.out.println("[]");
        }
    }

    public static void main(String[] args) {
        E_20 Linklist = new E_20();

        for (int i = 0; i < 10; i++) {
            Linklist.append(Integer.toString(i));
        }
        Linklist.display();

        Linklist.delete(6);

        Linklist.display();
        //[9->8->7->6->5->4->3->2->1->0]
        //删除元素为:4
        //[9->8->7->6->5->3->2->1->0]
    }
}

1.3.21

/**
 * 编写一个方法find() 接受一条链表和一个字符串key作为参数。如果链表某个节点的item域 的值为key,则返回
 * true,否则返回false
 */
public class E_21 {
    private int n;
    private Node first;

    public E_21(){
        n = 0;
        first = null;
    }
    //链表的每个节点类
    private static class Node{
        private String item;
        private Node next;
    }

    public void append(String item) {
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.next = oldfirst;
        n++;
    }

    /** 方法用起来很奇怪,不如C++的数据结构那么舒服....
     * @param linkList
     * @param Key
     * @return
     */
    public static boolean find(E_21 linkList,String Key){
        E_21 current = linkList;
        int temp = current.n;
        Node node = current.first;
        while(temp > 0){
            if (node.item.equals(Key)) return true;
            else node = node.next;
            temp--;
        }
        return false;
    }

    public static void main(String[] args) {
        E_21 linkList = new E_21();

        linkList.append("hello");
        linkList.append("java");
        linkList.append("world");
        linkList.append("mereder");
        linkList.append("python");

        if (find(linkList,"hello"))
            System.out.println("true");
        else System.out.println("false");

        if (find(linkList,"1111"))
            System.out.println("true");
        else System.out.println("false");

    }
}

1.3.22

/**
 * 假设x是一条链表中的某个结点,下面这段代码做了什么?
 */
public class E_22 {
    public static class Node{
        int item;
        Node next;
    }

    public static void main(String[] args) {
        Node first = new Node();
        first.item = 1;
        Node second = new Node();
        second.item = 2;
        Node t = new Node();
        t.item = 20;
        Node x = new Node();
        x.item = 10;
        //1->2->10
        first.next = second;
        second.next = x;
        x.next = null;
        //操作
        t.next = x.next;
        x.next = t;
        //1->2->10->20
        //插入t 结点  并使之成为x的后续结点
        while(first.next != null){
            System.out.println(first.item);
            first = first.next;
        }
        System.out.println(first.item);


    }
}

1.3.23

/**
 * 为什么下面这段代码和上道题中的代码效果不同
 */
public class E_23 {
    public static class Node{
        int item;
        Node next;
    }

    public static void main(String[] args) {
        Node first = new Node();
        first.item = 1;
        Node second = new Node();
        second.item = 2;
        Node t = new Node();
        t.item = 20;
        Node x = new Node();
        x.item = 10;
        //1->2->10
        first.next = second;
        second.next = x;
        x.next = null;
        //操作
        x.next = t;
        t.next = x.next;
        //           |--|
        //           v  |
        //1->2->10->20--    20结点形成环
        // 更新t.next时,x.next 已经不再指向x的后续结点,而是指向t本身
        //死循环!!!!!
        while(first.next != null){
            System.out.println(first.item);
            first = first.next;
        }
        System.out.println(first.item);

    }
}

1.3.24

public class E_24 {

    public static class Node{
        String item;
        Node next;
    }

    public static Node append(Node list,String item) {
        Node oldfirst = list;
        list = new Node();
        list.item = item;
        list.next = oldfirst;
        return list;
    }
    public static Node removeAfter(Node Linklist){
        if (Linklist == null || Linklist.next == null)
            return Linklist;
        else {
            Linklist.next = null;
            return Linklist;
        }

    }

    public static void main(String[] args) {
        Node Linklist = new Node();
        Linklist = null;
        Linklist = append(Linklist,"hello");
        Linklist = append(Linklist,"java");
        Linklist = append(Linklist,"world");
        Linklist = append(Linklist,"mereder");
        Linklist = append(Linklist,"python");

        Linklist = removeAfter(Linklist);

        System.out.println(Linklist.item);
    }
}

1.3.25

public class E_25 {
    public static class Node{
        String item;
        Node next;
    }

    public static Node append(Node list,String item) {
        Node oldfirst = list;
        list = new Node();
        list.item = item;
        list.next = oldfirst;
        return list;
    }
    public static Node insertAfter(Node firstList,Node secondList){
        if (firstList == null && secondList == null){ return null;}
        else if (firstList == null && secondList != null) return secondList;
        else if (firstList != null && secondList == null) return firstList;
        else {
            Node connetion = firstList.next;
            firstList.next = secondList;
            Node current = firstList;
            while (current.next != null){
                current = current.next;
            }
            current.next = connetion;
            return firstList;
        }

    }
    public static void main(String[] args) {
        Node Linklist = new Node();
        Node seondlist = new Node();
        Linklist = null;
        seondlist = null;

        Linklist = append(Linklist,"hello");
        Linklist = append(Linklist,"java");
        Linklist = append(Linklist,"world");


        seondlist = append(seondlist,"mereder");
        seondlist = append(seondlist,"python");
        //Linklist 为 world->java->hello
        // secondlist 为 python->mereder
        Node result = insertAfter(Linklist,seondlist);
        //处理结果为 world->python->mereder->java->hello
        while(result != null){
            System.out.println(result.item);
            result = result.next;
        }

    }
}

1.3.26

/**
 * 编写一个方法remove() 接受一条链表和一个字符串Key作为参数,删除链表中所有item域为key的结点
 */
public class E_26 {
    public static void remove(LinkList linkList,String Key){
        int temp = linkList.getSize();
        for (int i = 0;i < temp;i++){
            if (linkList.delete(Key)) continue;
        }
    }

    public static void main(String[] args) {
        LinkList Linklist = new LinkList();

        Linklist.addHead("hello");
        Linklist.addHead("java");
        Linklist.addHead("world");
        Linklist.addHead("mereder");
        Linklist.addHead("python");
        Linklist.addHead("world");

        Linklist.display();

        remove(Linklist,"world");

        Linklist.display();

    }
}

1.3.27

import edu.princeton.cs.algs4.StdRandom;

/**
 * 编写一个max()方法接受一条链表的首节点作为参数,返回链表中最大结点的值。假设所有键均为正整数。
 * 链表为空则返回0。
 */
public class E_27 {
    public static class Node{
        public int item;
        public Node next;
    }

    public static int Max(Node first){
        int max = 0;
        Node current = first;
        while(current != null){
            if (current.item > max) max = current.item;
            current = current.next;
        }
        return max;
    }

    public static int max = 0;
    public static int Recursion_Max(Node first){
        Node current = first;
        if (current == null) return max;
        else {
            if (current.item > max) max = current.item;
            return Recursion_Max(current.next);
        }
    }
    public static void main(String[] args) {
        Node first = new Node();
        Node n1 = new Node();
        Node n2 = new Node();
        Node n3 = new Node();
        Node n4 = new Node();

        first.item = StdRandom.uniform(1,20); first.next = n1;
        n1.item = StdRandom.uniform(1,20); n1.next = n2;
        n2.item = StdRandom.uniform(1,20); n2.next = n3;
        n3.item = StdRandom.uniform(1,20); n3.next = n4;
        n4.item = StdRandom.uniform(1,20); n4.next = null;

        int maxIterator = Max(first);
        System.out.println(maxIterator);

        int maxRecursion = Recursion_Max(first);
        System.out.println(maxRecursion);
    }
}

1.3.28

/**我....
 *
 */
public class E_28 {
}

1.3.29

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

/**
 * 环形链表实现Queue。环形链表也是一条链表,只是没有任何结点的链接为空,且只要链表非空,则last.next的值为first
 * 只能使用一个Node类型的实例变量Last
 */
public class Queue<Item> implements Iterable<Item> {
   // private Node<Item> first;    // beginning of queue
    private Node<Item> last;     // end of queue
    private int n;

    private static class Node<Item> {
        private Item item;
        private Node<Item> next;
    }

    public Queue() {
        last = null;
        n = 0;
    }

    public boolean isEmpty() {
        return n == 0;
    }
    public int size() {
        return n;
    }

    public void Enqueue(Item item) {
        Node<Item> oldlast = last;
        last = new Node<Item>();
        last.item = item;
        if (isEmpty())  last.next = last;
        else           {
            last.next = oldlast.next;
            oldlast.next = last;
        }
        n++;
    }
    public Item Dequeue(){
        if (isEmpty()) throw new NoSuchElementException("Queue underflow");
        Item item = last.next.item;
        last.next = last.next.next;
        n--;
        if (isEmpty()) last = null;   // to avoid loitering
        return item;
    }


    @Override
    public Iterator<Item> iterator() {
        return new ListIterator<Item>();}
    public class ListIterator<Item> implements Iterator<Item> {
        private Node<Item> current;
            @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() {

            }

        }


    public static void main(String[] args) {
        Queue<Integer> queue = new Queue<>();
        for (int i = 0; i < 10; i++) {
            queue.Enqueue(i);
        }

        int first = queue.Dequeue();
        int second = queue.Dequeue();
        System.out.println(first +" "+ second);
    }
}

1.3.30

/**
 * 编写一个函数,接受一条链表的首结点作为参数。(破坏性地)将链表反转,并返回结果链表的首结点
 */
public class E_30 {
    public static class Node<Item>{
        public Item item;
        public Node<Item> next;
    }

    /** 迭代解答记录链表中三个连续的结点:reverse first second
     * 在每轮迭代中,我们从原链表中提取结点first 并将它插入到逆链表的开头
     * 我们需要一直保持first指向原链表中所有剩余结点的首结点,second指向原链表中
     * 所有剩余结点的第二个结点,reverse指向结果链表的首结点
     *
     * 通俗来讲:reverse 就是一个新链表的首结点  first为即将插入reverse链表的结点,second始终为剩下的链表,
     * first每次需要指向将剩下链表的首结点,然后将second下移一个
     *
     * @param head
     * @return
     */
    public static Node iterationReverse(Node head){
        Node<Integer> reverse = null;
        Node<Integer> first = head;
        while(first != null){
            Node<Integer> second = first.next;
            first.next = reverse;
            reverse = first;
            first = second;
        }
        return reverse;
    }

    /**假设链表含有N个结点, 依次递归颠倒N-1个结点
     * @param head
     * @return
     */
    public static Node recursionReverse(Node head){
        if (head == null) return null;
        if (head.next == null) return head;
        Node second = head.next;
        Node rest = recursionReverse(second);
        second.next = head;
        head.next = null;
        return rest;
    }

    public static void main(String[] args) {
        Node<Integer> first = new Node<>();
        first.item = 1;
        Node<Integer> second = new Node<>();
        second.item = 2;
        Node<Integer> third = new Node<>();
        third.item = 3;
        Node<Integer> fourth = new Node<>();
        fourth.item = 4;
        first.next= second;second.next = third;third.next = fourth;fourth.next = null;

        Node<Integer> test = iterationReverse(first);
        System.out.println(test.item);

        Node<Integer> test2 = recursionReverse(test);
        System.out.println(test2.item);
    }
}

1.3.31

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

public class DoubleNode<Item> implements Iterable<Item> {
    private Node<Item> first;
    private Node<Item> last;
    private int n;

    private class Node<Item>{
        private Node<Item> previous;
        private Item item;
        private Node<Item> subsequent;

        public Node() {
            previous = null;
            subsequent = null;
        }
    }

    public DoubleNode() {
        first = null;
        last = null;
        n = 0;
    }
    public int getN() { return n; }

    public boolean isEmpty(){ return  n ==  0;}

    /**表头插入结点
     * @param item
     */
    public void Head_add(Item item){
        Node<Item> newHead = new Node<>();
        newHead.item = item;
        if (isEmpty()){
            first = newHead;
            last = first;
        }
        else {
            newHead.subsequent = first;
            first.previous = newHead;
            first = newHead;
        }
        n++;
    }

    /**表尾插入结点
     * @param item
     */
    public void Tail_add(Item item){
        Node<Item> newTail = new Node<>();
        newTail.item =  item;
        if (isEmpty()){
            last = newTail;
            first = last;
        }
        else {
            newTail.previous = last;
            last.subsequent = newTail;
            last = newTail;
        }
        n++;
    }

    public Item deleteHead(){
        if (isEmpty()) throw new NoSuchElementException("No Node");
        Item item = first.item;

        first = first.subsequent;
        first.previous = null;
        n--;
        return item;
    }

    public Item deleteTail(){
        if (isEmpty()) throw new NoSuchElementException("No Node");
        Item item = last.item;
        n--;
        last = last.previous;
        last.subsequent = null;
        return item;
    }

    public boolean insertBeforeSpecific(Item Key,Item insertItem){
        if(n == 0){
            return false;
        }
        Node newnode = new Node();
        newnode.item = insertItem;

        Node current = first;
        while (current != null){
            if (current.item.equals(Key)){
                if (current.previous == null){
                    current.previous = newnode;
                    newnode.subsequent = current;
                    first = newnode;
                }
                else {
                    current.previous.subsequent = newnode;
                    newnode.subsequent = current;
                    newnode.previous = current.previous;
                    current.previous = newnode;
                }
                n++;
                return true;
            }
            else {
                current = current.subsequent;
            }
        }
        return false;
    }

    public boolean insertAfterSpecific(Item Key,Item insertItem){
        if(n == 0){
            return false;
        }
        Node newnode = new Node();
        newnode.item = insertItem;

        Node current = first;
        while(current != null){
            if (current.item.equals(Key)){
                if (current.subsequent == null){
                    current.subsequent = newnode;
                    newnode.previous = current;
                    last = newnode;
                }
                else {
                    current.subsequent.previous = newnode;
                    newnode.subsequent = current.subsequent;
                    current.subsequent = newnode;
                    newnode.previous = current;
                }
                n++;
                return true;
            }
            else {
                current = current.subsequent;
            }
        }
        return false;

    }

    public boolean deleteSpecific(Item Key){
        if(n == 0){
            return false;
        }
        Node current = first;
        while(current.subsequent != null) {
            if (current.item.equals(Key)){
                if (current.previous == null){
                    first = first.subsequent;
                    first.previous = null;
                }
                else if (current.subsequent == null){
                    last = last.previous;
                    last.subsequent = null;
                }
                else {
                    current.previous.subsequent = current.subsequent;
                    current.previous.subsequent.previous = current.previous;
                }
                n--;
                return true;
            }
            else {
                current = current.subsequent;
            }
        }
        return false;
    }

    @Override
    public Iterator iterator() {
        return null;
    }

    public static void main(String[] args) {
        DoubleNode<Integer> test = new DoubleNode<>();
        test.Head_add(1);
        //-1-
        if (test.insertBeforeSpecific(1,3)) System.out.println("insert correctly");
        else System.out.println("error");
        //-3<=>1-
        if (test.insertAfterSpecific(1,4)) System.out.println("insert correctly");
        else System.out.println("error");
        //-3<=>1<=>4-
        test.Head_add(2);
        //-2<=>3<=>1<=>4-
        if (test.deleteSpecific(1)) System.out.println("delete correctly");
        else System.out.println("error");
        //-2<=>3<=>4-
        test.Tail_add(9);
        //-2<=>3<=>4<=>9-
        test.Tail_add(10);
        //-2<=>3<=>4<=>9<=>10-
        test.deleteHead();
        //-3<=>4<=>9<=>10-
        test.deleteTail();
        //-3<=>4<=>9-
        System.out.println(test.first.item);
    }
}

1.3.32

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

/**1.3.32 Steque
 * =======================================================================
 * public class Steque<Item> implements Iterable<Item>
 * -----------------------------------------------------------------------
 *        public Steque(); 默认构造函数。
 *        public bool isEmpty(); 检查 Steque 是否为空。
 *        public int getSize(); 返回 Steque 中的元素数量。
 *        public void Push(Item item); 向 Steque 中压入一个元素。
 *        public Item Pop(); 从 Steque 中弹出一个元素。
 *        public void Enqueue(Item item); 将一个元素添加入 Steque 中
 *        public Iterator<Item> iterator(); 实现迭代
 *        ================================================================
 *        public class ListIterator<Item> implements Iterator<Item>
 *            ------------------------------------------------------------
 *              public ListIterator(Node<Item> current)
 *              public boolean hasNext() {
 *              public Item next()
 */
public class Steque<Item> implements Iterable<Item> {
    private Node<Item> QueueLast;
    private Node<Item> StackTop;
    private int  n;

    private static class Node<Item> {
        private Item item;
        private Node<Item> next;

        public Node() {
             next = null;
        }
    }

    public Steque() {
        QueueLast = null;
        StackTop = null;
        n = 0;
    }
    public boolean isEmpty(){
        return n == 0;
    }

    public int getSize() {
        return n;
    }

    public void Push(Item item){

        Node<Item> oldlist = StackTop;
        StackTop = new Node<>();
        StackTop.item = item;
        if (isEmpty()) {
            QueueLast = StackTop;
        }
        StackTop.next = oldlist;
        n++;
    }
    public Item Pop(){
        if (isEmpty()) throw new NoSuchElementException("stack  underflow");
        Item item = StackTop.item;
        StackTop = StackTop.next;
        n--;
        return item;
    }

    public void Enqueque(Item item){
        Node<Item> oldLast = QueueLast;
        QueueLast = new Node<>();
        QueueLast.item = item;
        QueueLast.next = null;
        if (isEmpty()) StackTop = QueueLast;
        else oldLast.next = QueueLast;
        n++;
    }

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

        public ListIterator(Node<Item> current) {
            this.current = current;
        }

        @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 ;
        }
    }

    public static void main(String[] args) {
        Steque<Integer> steque = new Steque<>();
        steque.Push(1);
        steque.Push(2);
        steque.Enqueque(3);

        for (Integer current :steque) {
            System.out.println(current);
        }

        steque.Pop();
        System.out.println("弹栈后:");
        for (Integer current :steque) {
            System.out.println(current);
        }
    }
}

1.3.33

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

/** 1.3.33 Deque
 *========================================================================
 * public class Deque<Item> implements Iterable<Item>
 * -----------------------------------------------------------------------
 *        public Deque();                  //创建空双向队列
 *        public boolean isEmpty();        //双向队列是否为空
 *        public int size()                //双向队列中的元素数量
 *        public void pushLeft(Item item)  //向左端添加一个新元素
 *        public void pushRight(Item item) //向右端添加一个新元素
 *        public Item popLeft()            //从左端删除一个元素
 *        public Item popRight()           //从右端删除一个元素
 */
public class Deque<Item> implements Iterable<Item> {
    private Node<Item> Left;
    private Node<Item> Right;
    private int n ;

    private static class Node<Item>{
        private Node<Item> previous;
        private Item item;
        private Node<Item> subsequent;

        public Node() {
            previous = null;
            subsequent = null;
        }
    }

    public Deque() {
        Left = null;
        Right = null;
        n = 0;
    }

    public int size() {
        return n;
    }

    /**双向队列是否为空
     * @return
     */
    public boolean isEmpty(){ return  n == 0;}

    /**向左端添加一个新元素
     * @param item
     */
    public void pushLeft(Item item){
        Node<Item> oldlist = Left;
        Left = new Node<>();
        Left.item = item;
        if (isEmpty()){
            Left.subsequent = oldlist;
            Left.previous = oldlist;
            Right = Left;
        }
        else {
            Left.subsequent = oldlist;
            oldlist.previous = Left;
        }
        n++;
    }

    /** 向右端添加一个新元素
     * @param item
     */
    public void pushRight(Item item){
        Node<Item> oldlist = Right;
        Right = new Node<>();
        Right.item = item;
        if (isEmpty()){
            Right.subsequent = oldlist;
            Right.previous = oldlist;
            Left = Right  ;
        }
        else {
            Right.previous = oldlist;
            oldlist.subsequent = Right;
        }
        n++;
    }

    /** 从左端删除一个元素
     * @return
     */
    public Item popLeft(){
        if (isEmpty()) throw new NoSuchElementException("Stack underflow");
        Item item  = Left.item;
        Left = Left.subsequent;
        Left.previous = null;
        n--;
        return item;
    }

    /** 从右端删除一个元素
     * @return
     */
    public Item popRight(){
        if (isEmpty()) throw new NoSuchElementException("Stack underflow");
        Item item  = Right.item;
        Right = Right.previous;
        Right.subsequent = null;
        n--;
        return item;
    }

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

        public ListIterator(Node<Item> current) {
            this.current = current;
        }

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

        @Override
        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.subsequent;
            return item ;
        }
    }
    public void display(){
        for (Item current :this) {
            System.out.print(current+" ");
        }
        System.out.println();
    }


    public static void main(String[] args) {
        Deque<Integer> deque = new Deque<>();

        System.out.println("左压栈:");
        deque.pushLeft(1);
        deque.pushLeft(2);
        deque.pushLeft(3);
        deque.pushLeft(4);
        deque.display();

        System.out.println("右压栈:");
        deque.pushRight(9);
        deque.pushRight(8);
        deque.display();

        System.out.println("左出栈:");
        int left = deque.popLeft();
        System.out.println("弹出:"+left);
        deque.display();

        System.out.println("右出栈:");
        int right = deque.popRight();
        System.out.println("弹出:"+right);
        deque.display();

    }
}

1.3.34

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

public class RandomBag<Item> implements Iterable<Item> {
    private Item[] Bag;
    private int n;               // number of elements in bag

    // helper linked list class

    public RandomBag() {
        Bag = (Item[]) new Object[1];
        n = 0;
    }
    public boolean isEmpty() {
        return n == 0;
    }

    public int size() {
        return n;
    }

    public void add(Item item) {
        if (n == Bag.length) Resizing(2 * Bag.length);
        Bag[n++] =  item;
    }

    private void Resizing(int capacity) {
        if (capacity <= 0) throw new NoSuchElementException(" ");
        Item[] temp = (Item[]) new Object[capacity];
        for (int i = 0; i < n; ++i)
        {
            temp[i] = Bag[i];
        }
        Bag = temp;
    }


    @Override
    public Iterator<Item> iterator()  {
        return new ListIterator<>();
    }

    // an iterator, doesn't implement remove() since it's optional
    private class ListIterator<Item> implements Iterator<Item> {

        public ListIterator() {
            Random((Item[]) Bag);
        }

        public void Random(Item[] Bag){
            for (int i = 0; i < n; i++) {
                int r=i+(int)(Math.random()*(n-i));
                Item temp = Bag[i];
                Bag[i] = Bag[r];
                Bag[r] = temp;
            }
        }
        public boolean hasNext()  { return n != 0;                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = (Item) Bag[--n];
            return item;
        }
    }

    public static void main(String[] args) {
        RandomBag<Integer> randomBag = new RandomBag<>();

        for (int i = 0; i < 20; i++) {
            randomBag.add(i);
        }

        for (Integer item:randomBag) {
            System.out.print(item + " ");
        }
    }
}

1.3.35(没有写桥牌)

import edu.princeton.cs.algs4.StdRandom;

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

public class RandomQueue<Item> implements Iterable<Item> {
    private Item[] Queue;
    private int n;


    public RandomQueue() {
         n = 0;
         Queue = (Item[]) new Object[1];
    }

    public boolean isEmpty(){ return n == 0;}

    public int size(){ return  n; }

    public void Enqueue(Item item ){
        if(n == Queue.length) Resizing( 2 * Queue.length);
        Queue[n++] = item;
    }

    private void Resizing(int max) {
        if (max <=  0 ) throw  new NoSuchElementException();
        Item[] temp = (Item[]) new Object[max];
        for (int i = 0; i < n; i++) {
            temp[i] = Queue[i];
        }
        Queue = temp;
    }

    public void Random(){
        int r = StdRandom.uniform(0,n);  // 左闭右开集合
        Item temp = Queue[r];
        Queue[r] =  Queue[n-1];
        Queue[n-1] = temp;
    }
    /**随机返回一个元素并删除它
     * @return
     */
    public Item Dequeue(){
        if (isEmpty()) throw new NoSuchElementException("no data");

        Random();

        Item item = Queue[--n];
        Queue[n] = null;
        if (n > 0 && n == Queue.length/4) Resizing(Queue.length/2);
        return item;
    }

    /** 随机返回一个元素但不删除它
     * @return
     */
    public Item Sample(){
        if (isEmpty()) throw new NoSuchElementException("No data");
        Random();
        Item item = Queue[n-1];
        return item;
    }

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

        public ListIterator() {
            Random();
        }

        @Override
        public boolean hasNext() {
            return n != 0;
        }

        @Override
        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = (Item) Queue[--n];
            return item;
        }

        @Override
        public void remove() {

        }
    }

    public static void main(String[] args) {
        RandomQueue<Integer> randomQueue = new RandomQueue<>();
        for (int i = 0; i < 10; i++) {
            randomQueue.Enqueue(i);
        }

        System.out.println(randomQueue.Dequeue());

        for (Integer temp :
                randomQueue) {
            System.out.print(temp+" ");
        }
    }
}

1.3.36 (见上一题 )

1.3.37

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

/**
 * Josephus 环问题
 */
public class Josephus {
    public static void main(String[] args) {
        System.out.println("输入N和M:");
        int N = StdIn.readInt();
        int M = StdIn.readInt();

        // initialize the queue

        Queue<Integer> queue = new Queue<Integer>();
        for (int i = 0; i < N; i++)
            queue.enqueue(i);

        while (!queue.isEmpty()) {
            for (int i = 0; i < M-1; i++)
                queue.enqueue(queue.dequeue());
            StdOut.print(queue.dequeue() + " ");
        }
        StdOut.println();
    }
}

1.3.38(数组实现)

import java.util.NoSuchElementException;

/**
 * 数组实现该数据类型
 * public class GeneralizedQueueOfArray<Item>
 *     ====================================================================
 *     public GeneralizedQueueOfArray()           创建一条空队列
 *     public boolean isEmpty()                   队列是否为空
 *     public void insert(Item item)              添加一个元素
 *     public Item delete(int k)                  删除并返回最早插入的第K个元素
 */
public class GeneralizedQueueOfArray<Item> {
    private Item[] Queue;
    private int n;

    public GeneralizedQueueOfArray() {
        Queue = (Item[]) new Object[1];
        n = 0;
    }
    public int size() { return n; }
    public boolean isEmpty(){ return n == 0; }

    private void Resizing(int max) {
        if (max <=  0 ) throw  new NoSuchElementException();
        Item[] temp = (Item[]) new Object[max];
        for (int i = 0; i < n; i++) {
            temp[i] = Queue[i];
        }
        Queue = temp;
    }
    public void insert(Item item){
        if (n == Queue.length) Resizing(2 * Queue.length);
        Queue[n++] = item;
    }

    public Item delete(int k){
        if (isEmpty()) throw new NoSuchElementException("No data");
        if (k > n) throw new NoSuchElementException("too large k");
        Item item =  Queue[k-1];
        Queue[k-1] = null;
        Item[] temp = (Item[]) new Object[n];
        for (int i = 0; i < k-1; i++) {
            temp[i] = Queue[i];
        }
        for (int i = k-1; i < n ; i++) {
            temp[i] = Queue[i+1];
        }
        Queue = temp;
        n--;
        return item;
    }

    public static void main(String[] args) {
        GeneralizedQueueOfArray<Integer> test = new GeneralizedQueueOfArray<>();
        for (int i = 0; i < 10; i++) {
            test.insert(i);
        }
        System.out.println(test.delete(5));

        System.out.println(test.delete(5));

    }
}

1.3.38(链表实现)

import java.util.NoSuchElementException;

public class GeneralizedQueueOfLinklist<Item> {
    private Node<Item> first;    // beginning of queue
    private Node<Item> last;     // end of queue
    private int n;               // number of elements on queue

    // helper linked list class
    private static class Node<Item> {
        private Item item;
        private Node<Item> next;
    }
    public GeneralizedQueueOfLinklist() {
        first = null;
        last  = null;
        n = 0;
    }

    public boolean isEmpty() {
        return first == null;
    }

    public int size() {
        return n;
    }

    public void insert(Item item) {
        Node<Item> oldlast = last;
        last = new Node<Item>();
        last.item = item;
        last.next = null;
        if (isEmpty()) first = last;
        else           oldlast.next = last;
        n++;
    }

    public Item delete(int k) {
        Item item;
        if (isEmpty()) throw new NoSuchElementException("Queue underflow");
        if (k > n || k <= 0){
           throw new NoSuchElementException("error k");
        }
        else if (k == 1){
            item = first.item;
            first = first.next;
        }
        else {
            Node<Item> current = first;
            for (int i = 0; i < k - 2; i++) {
                current = current.next;
            }
             item = current.next.item;
            current.next = current.next.next;
        }
        n--;
        if (isEmpty()) last = null;   // to avoid loitering
        return item;
    }

    public static void main(String[] args) {
        GeneralizedQueueOfLinklist<Integer> test1 = new GeneralizedQueueOfLinklist<>();
        for (int i = 0; i < 10; i++) {
            test1.insert(i);
        }

        System.out.println(test1.delete(5));

        System.out.println(test1.delete(2));

    }
}

1.3.39

import edu.princeton.cs.algs4.StdRandom;

import java.util.NoSuchElementException;

/**
 * 环形缓冲区:
 * 环形缓冲区,又称环形队列,是一种定长为 N 的先进先出的数据结构。它在进程间的异步数据传输或记录
 * 日志文件时十分有用。当缓冲区为空时,消费者会在数据存入缓冲区前等待;当缓冲区满时,生产者会等待
 * 将数据存入缓冲区。设计一份API并用(回环)数组将其实现。
 */
public class RingBuffer<Item> {
    private Item[] ringBuffer;
    private int n;
    private int first;
    private int last;

    public RingBuffer( int N) {
        ringBuffer = (Item[]) new Object[N];
        this.n = 0;
        this.first = 0;
        this.last = 0;
    }
    public boolean isFull(){ return n == ringBuffer.length; }
    public boolean isEmpty(){ return n == 0; }

    public void WriteBuffer(Item item){
        if (isFull()) throw new OutOfMemoryError("Buffer is full");
        ringBuffer[last] = item;
        last = (last + 1) % ringBuffer.length;
        n++;
    }

    public Item ReadBuffer(){
        if (isEmpty()) throw new NoSuchElementException("Buffer is empty");
        Item item = ringBuffer[first];
        first = (first + 1) % ringBuffer.length;
        n--;
        return item;
    }


    public static void main(String[] args) {
        RingBuffer<Integer> buffer = new RingBuffer<>(10);

        //模拟生产消费随机过程,进程并发
        // 学了多线程 再来修改这部分
        for (int i = 0; i < 10; i++) {
            int rand = StdRandom.uniform(1,100);
            if (rand % 5 == 0) System.out.println(buffer.ReadBuffer());
            else buffer.WriteBuffer(rand);
        }
    }
}

1.3.40

import edu.princeton.cs.algs4.StdIn;

public class MoveToFront {
    private Node head;
    private int n;

    private class Node{
        private char item;
        private Node next;
    }

    public MoveToFront() {
        this.head = null;
        this.n = 0;
    }

    public void add(char ch){
        Node oldfirst = head;
        head = new Node();
        head.item = ch;
        head.next = oldfirst;
        n++;
    }
    /**检测是否重复,且将重复的删掉
     * @param ch
     * @return
     */
    public boolean isRepeat(char ch){
        if (head == null ) return false;
        else if (head.item == ch) {
            head = null;
            return true;
        }
        Node current = head;
        while(current.next != null){
            if (current.next.item == ch){
                current.next = current.next.next;
                return true;
            }
            current = current.next;
        }
        return false;
    }

    public void operate(char[] chars){
        int N = chars.length;
        for (int i = 0; i < N; i++) {
            char ch = chars[i];
            if (isRepeat(ch)) {
                add(ch);
            }
            else {
                add(ch);
            }
        }
    }
    public String toString()
    {
        String ret = "";
        if (head == null)
            return ret;
        Node current = head;
        ret += head.item;
        while (current.next != null)
        {
            ret = ret + " " + current.next.item;
            current = current.next;
        }
        return ret;
    }

    public static void main(String[] args) {
        MoveToFront test = new MoveToFront();
        char[] data = {'1','2','4','2','3','1','5','1'};
        test.operate(data);
        //result 1 5 3 2 5
        System.out.println(test);
    }
}

1.3.41

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

/**
 * 复制队列 编写一个新的构造函数
 * Queue<Item> r = new Queue<Item>(q);
 *
 */
public class CopyQueue {
    public static void main(String[] args) {
        Queue<String> queue = new Queue<String>();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            queue.enqueue(item);
        }
        // 调用 复制队列的构造函数 在 edu.princeton.cs.algs4.Queue 中实现
        Queue<String> copyqueue = new Queue<>(queue);
        System.out.println(queue);
        //测试不互相影响
        queue.dequeue();

        System.out.println(queue);

        System.out.println(copyqueue);
    }
}

1.3.42

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

/**
 * 复制栈;为基于链表实现的栈编写一个新的构造函数
 */
public class CopyStack {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<String>();
        while (!StdIn.isEmpty()) {
            String item = StdIn.readString();
            stack.push(item);
        }
        System.out.println(stack);
        // 调用 复制栈的构造函数 在 edu.princeton.cs.algs4.Stack 中实现
        Stack<String> test = new Stack<>(stack);
        //测试测试不互相影响
        stack.push("test");
        System.out.println(stack);
        System.out.println(test);

    }
}

1.3.43

import java.io.File;

public class FileList {
    // 这个队列用的很奇怪,过程中队列中都是只有一个元素
    Queue<File> queue = new Queue<>();
    
    public void addQueue(File file,int depth){

        if (file.exists()){
            queue.Enqueue(file);
            for (int i = 0; i < depth; i++) {
                System.out.print("\t");
            }
            System.out.println(queue.Dequeue().getName());
            if (file.isDirectory()){
                File[] list = file.listFiles();
                for (File temp:list){
                    addQueue(temp,depth+1);
                }
            }
            else
                return;
        }
        else return;
    }

    public static void main(String[] args) {
       FileList test = new FileList();
       String rootname = "E:\\filetest";
       File root = new File(rootname);
       test.addQueue(root,0);
       System.out.println();
    }

}

1.3.44

import edu.princeton.cs.algs4.Stack;

import java.util.NoSuchElementException;

/**
 * 文本编辑器缓冲区
 *
 */
public class Buffer {
    private Stack<Character> left;
    private Stack<Character> right;
    private int leftnum;
    private int rightnum;
    /**
     * 创建一块空缓冲区
     */
    public Buffer() {
        left = new Stack<>();
        right = new Stack<>();
        leftnum = 0;
        rightnum  = 0;
    }

    public void insert(char c){
        left.push(c);
        leftnum++;
    }

    public char delete(){
        if (left.isEmpty()) throw new NoSuchElementException("No content to delete");
        char ch = left.pop();
        leftnum--;
        return ch;
    }
    public void left(int k){
        if (k <= 0) throw new NoSuchElementException("error k");
        if (leftnum < k)
        {
            System.out.println("no enough char to move,Already moving to the head");
            for (int i = 0; i < leftnum; i++) {
                right.push(left.pop());
            }
            rightnum += leftnum;
            return;
        }
        for (int i = 0; i < k; i++) {
            right.push(left.pop());
            leftnum--;
            rightnum++;
        }
    }

    public void right(int k){
        if (k <= 0) throw new NoSuchElementException("error k");
        if (rightnum < k)
        {
            System.out.println("no enough char to move,Already moving to the tail");
            for (int i = 0; i < rightnum; i++) {
                left.push(right.pop());
            }
            leftnum += rightnum;
            return;
        }
        for (int i = 0; i < k; i++) {
            left.push(right.pop());
            rightnum--;
            leftnum++;
        }
    }

    public int size(){
        return leftnum+rightnum;
    }
    public void  display(){

        Stack<Character> temp = new Stack<>();
        while(!left.isEmpty()){
            temp.push(left.pop());
        }
        for (Character ch : temp) {
            left.push(ch);
            System.out.print(ch);
        }
        System.out.print('|');
        temp = new Stack<>();
        for (Character ch : right) {
            temp.push(ch);
            System.out.print(ch);
        }
        for (Character ch : temp) {
            right.push(ch);
        }
        System.out.println();
    }
    public static void main(String[] args) {
        Buffer test = new Buffer();

        for (int i = 0; i < 10; i++) {
            test.insert(String.valueOf(i).charAt(0));
        }
        test.display();
        test.right(2);
        test.display();
        test.left(2);
        test.display();
    }
}

1.3.45

import edu.princeton.cs.algs4.Stack;

/**
 * 栈的可生成性
 */
public class E_45 {
    public static boolean isUnderFlow(String sequence){
        int pushtimes = 0;
        int poptimes = 0;
        for (int i = 0; i < sequence.length(); i++) {
            char ch = sequence.charAt(i);
            if (Character.isDigit(ch)) pushtimes++;
            else if (ch == '-') poptimes++;
            else continue;

            if (poptimes > pushtimes) return true;
            else continue;
        }
        return  false;
    }

    public static boolean judge(int[] GivenSequence){
        Stack<Integer> stack = new Stack<>();
        int push = 0;
        for (int i = 0; i < GivenSequence.length; i++) {
                if (stack.isEmpty()){
                    stack.push(push);
                    push++;
                }
                while(stack.peek()!= GivenSequence[i]){
                    stack.push(push);
                    push++;
                }
                stack.pop();
        }

        return stack.isEmpty();

    }

    public static void main(String[] args) {
        String sequence1 = "0 1 2 3 4 - - - - - 5 6 7 8 9 - - - - -";
        String sequence2 = "0 1 2 3 4 - 5 6 - - - - - - - 7 8 9 - -";
        if (isUnderFlow(sequence2)) System.out.println("flow");
        if (isUnderFlow(sequence1)) System.out.println("flow");
        else System.out.println("No");

        int[] GivenSequence = {4,3,2,1,0,9,8,7,6,5};
        if (judge(GivenSequence)) System.out.println("ok");
        else System.out.println("No");

        System.out.println();
    }

}

1.3.46 ...

转载于:https://www.cnblogs.com/mereder/p/9672152.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值