1.stacks
1.利用数组表示栈
2.利用链表表示栈
2.resizing arrays
3.queues
3.1利用链表表示队列
4.generics
泛型
4.1 使用链表实现的栈泛化
4.2使用数组实现的栈泛化
3.iterators
Interview Questions: Stacks and Queues
- 利用两个栈来实现队列,具体方法为:入队等同于栈A进栈;出队时如果栈B不空,则栈B出栈,如果栈B为空,则依次将栈A元素出栈,并压入栈B。(因Stack被官方不推荐,采用LinkedList来实现栈结构)
import java.util.LinkedList;
public class StackQueue<E> {
LinkedList<E> stackA;
LinkedList<E> stackB;
public StackQueue() {
stackA = new LinkedList<>();
stackB = new LinkedList<>();
}
public boolean isEmpty() {
return stackA.isEmpty() && stackB.isEmpty();
}
public void enqueue(E item) {
stackA.push(item);
}
public E dequeue() {
if (stackB.isEmpty()) {
if (stackA.isEmpty()) {
return null;
}
while (!stackA.isEmpty()) {
E temp = stackA.pop();
stackB.push(temp);
}
}
return stackB.pop();
}
public int size() {
return stackA.size() + stackB.size();
}
}
2.维护两个栈来实现输出最大值:一个为普通栈stack,一个用于保存与当前普通栈中元素相对应的最大值栈maxStack。push新元素x时,如果当前maxStack为空,或者x值大于等于maxStack栈顶元素,说明x是加入后普通栈中的最大值,需要在maxStack入栈;pop栈顶元素x时,如果x与maxStack栈顶元素相同,说明x正是当前普通栈中的最大值,也需要在maxStack出栈。
import java.util.LinkedList;
public class MaxStack {
private LinkedList<Integer> stack;
private LinkedList<Integer> maxStack;
public MaxStack() {
stack = new LinkedList<>();
maxStack = new LinkedList<>();
}
public boolean isEmpty() {
return stack.isEmpty();
}
public void push(int x) {
if (maxStack.isEmpty() || x >= maxStack.peek()) {
maxStack.push(x);
}
stack.push(x);
}
public void pop() {
// 注意不能用stack.peek()==maxStack.peek()进行判断,
// 这样做比较的是Integer对象本身而不是int值
int max = maxStack.peek();
if (stack.peek() == max) {
maxStack.pop();
}
stack.pop();
}
public int findMax() {
return maxStack.peek();
}
}
Deques and Randomized Queues
Deque.java
import java.utol.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item>
{
private Node first=null;
private Node last=null;
private int size=0;
public Deque() {}
public int size(){
return size;
}
public boolean isEmpty()
{
return first==null;
}
public void addfirst(Item item)
{
if(item==null)
{
throw new IllegalArgumentException();
}
size++;
Node oldfirst=first;
first=new Node();
first.item=item;
if(oldfirst==null)
{
first=last;
return;
}
oldlast.prev=first;
first.next=oldfisrt;
}
//入队
public void addlast(String item)
{
if(item==null)
{
throw new IllegalArgumentException();
}
size++;
Node oldlast=last;
last=new Node();
last.item=item;
last.next=null;
if(oldlast==null)
{
first=last;
return;
}
oldlast.next=last;
last.prev=oldlast;
}
//出队
public Item removeFirst()
{
if (isEmpty()) {
throw new NoSuchElementException();
}
Item item=first.item;
first=first.next;
if(isEmpty()) last=null;
else first.prev=null;
size--;
return item;
}
public Item removelast()
{
if (isEmpty()) {
throw new NoSuchElementException();
}
Item item=last.item;
last=last.prev;
if(last==null) first=null;
else last.next=null;
size--;
return item;
}
public Iterator<Item> iterator()
{
return new DequeIterator();
}
private class Node{
Item item;
Node next;
Node prev;
}
private class DequeIterator implements Iterator<Item>
{
private Node current=first;
@Override
public boolean hasNext()
{
return current!=null;
}
public Item next()
{
if (!hasNext()) {
throw new NoSuchElementException();
}
Item item=current.item;
current=current.next;
return item;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
// 需要调用构造器和所有的公开方法
public static void main(String[] args) {
Deque<String> dq = new Deque<>();
dq.addFirst("1");
dq.addLast("2");
dq.addFirst("3");
dq.addLast("4");
System.out.println(dq.size());
dq.removeFirst();
dq.removeLast();
System.out.println(dq.isEmpty());
Iterator<String> it = dq.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
RandomizedQueue.java
import edu.princeton.cs.algs4.StdRandom;
import java.util.Iterator;
import java.util.NoSuchElementException;
//resizing-array(分摊时间) generic
public class RandomizedQueue<Item> implements Iterable<Item>
{
private int N;
private Item[] s;
//构造一个空的随机队列
public RandomizedQueue()
{
s=(Item[]) new Object[1];//s=new String[1]数组
}
public boolean isEmpty()
{
return N==0;
}
public int size()
{
return N;
}
public void push(Item item)
{
if(item==null)
{
throw new IllegalAccessException();
}
if(N==s.length) resize(2*s.length);
s[N++]=item;
}
public Item pop()
{
if(isEmpty())
{
throw new IllegalAccessException();
}
int random=StdRandom.uniform(N);
Item res=s[random];
s[random]=s[--N];
s[N]=null;
if(N>0&&N==s.length/4) resize(s.length/2);
return res;
}
public Item sample()
{
if (isEmpty()) {
throw new NoSuchElementException();
}
int random = StdRandom.uniform(N);
return s[random];
}
public Iterator<Item> iterator()
{
return new RQIterator();
}
private class RQIterator implements Iterator<Item>
{
private Item[] temp=(Item[])new Object[N];
private int size=N;
public RQIterator(){
for(int i=0;i<N;i++)
{
temp[i]=s[i];
}
}
@Override
public boolean hasNext()
{
return size>0;
}
public Item next()
{
if (!hasNext()) {
throw new NoSuchElementException();
}
int random=StdRandom.uniform(size);
Item res=temp[random];
temp[random]=temp[--size];
temp[size]=null;
return res;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private void resize(int size) {
Item[] temp = (Item[]) new Object[size];
for (int i = 0; i < N; i++) {
temp[i] = s[i];
}
s = temp;
}
// unit testing (required)
// 需要调用构造器和所有的公开方法
public static void main(String[] args) {
RandomizedQueue<String> rq = new RandomizedQueue<>();
rq.push("1");
rq.push("2");
rq.push("3");
rq.push("4");
System.out.println(rq.size());
System.out.println(rq.sample());
rq.pop();
System.out.println(rq.isEmpty());
Iterator<String> it = rq.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
Permutation.java
import edu.princeton.cs.algs4.StdIn;
public class Permutation {
public static void main(String[] args) {
RandomizedQueue<String> rq = new RandomizedQueue<>();
int k = Integer.parseInt(args[0]);
// 实际需要读取的个数n并没有给出
while (!StdIn.isEmpty()) {
rq.push(StdIn.readString());
}
for (int i = 0; i < k; i++) {
System.out.println(rq.pop());
}
}
}