Stack and Queue 栈和队列

本文介绍了栈和队列的基本概念及其在Java中的实现方式,包括接口定义、链表与数组实现。栈遵循后进先出(LIFO)原则,队列则为先进先出(FIFO)。此外,文章还探讨了双端队列(Deque)的特性,它可以作为栈(头进头出)和队列(尾进头出)使用,并举例说明了双端队列在Dijkstra's two stack algorithm计算表达式及十进制转二进制等场景的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈:

接口定义:

public interface Stack<T> extends Iterable<T> {
	/**
	 * Check if the stack is empty.
	 * @return True if it is empty. False otherwise.
	 */
	public boolean isEmpty();
	
	/**
	 * Get the size of the stack.
	 * @return Size
	 */
	public int size();
	
	/**
	 * Get the top of the stack.
	 * @return Top of the stack.
	 */
	public T peek();
	
	/**
	 * Push an item to the stack 
	 * @param item Item to be pushed.
	 */
	public void push(T item);

	/**
	 * Pop an item from the stack.
	 * @param item Item to be popped.
	 * @return Item
	 */
	public T pop();
	
	/**
	 * 
	 * Search the position of the item in the stack
	 * @param item Item
	 * @return Position of item. -1 if non-exists.
	 */
	public int search(T item);
	
}

链表实现:

public class LinkedListStack<T> implements Stack<T> {
	private Node top;
	private int size;

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public T peek() {
		if (size == 0) {
			return null;
		}
		return top.item;
	}

	@Override
	public void push(T item) {
		Node node = new Node(item);
		node.next = top;
		top = node;
		size++;
	}

	@Override
	public T pop() {
		if (size == 0) {
			return null;
		}
		T item = top.item;
		top = top.next;
		size--;
		return item;
	}

	@Override
	public int search(T item) {
		if (size == 0 || item == null) {
			return -1;
		}
		Node current = top;
		int index = 0;
		while (current != null) {
			if (current.item.equals(item)) {
				return index;
			}
			current = current.next;
			index++;
		}
		return -1;
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			Node current = top;

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

			@Override
			public T next() {
				T item = current.item;
				current = current.next;
				return item;
			}
		};
	}

	private class Node {
		T item;
		Node next;

		Node(T item) {
			this.item = item;
		}
	}

}


数组实现:

public class ArrayStack<T> implements Stack<T> {
	private T[] stack;
	private int top;

	@SuppressWarnings("unchecked")
	public ArrayStack() {
		stack = (T[]) new Object[4];
		top = -1;
	}

	@Override
	public boolean isEmpty() {
		return top == -1;
	}

	@Override
	public int size() {
		return top + 1;
	}

	@Override
	public T peek() {
		if (top == -1) {
			return null;
		}
		return stack[top];
	}

	@Override
	public void push(T item) {
		if (top + 1 == stack.length) {
			resize(stack.length * 2);
		}
		stack[++top] = item;
	}

	@Override
	public T pop() {
		if (top == -1) {
			return null;
		}
		T item = stack[top];
		stack[top--] = null;
		if (stack.length > 4 && top + 1 == stack.length / 4) {
			resize(stack.length / 2);
		}
		return item;
	}

	@Override
	public int search(T item) {
		if (item == null) {
			return -1;
		}
		int current = top;
		while (current >= 0) {
			if (stack[current].equals(item)) {
				return top - current;
			}
			current--;
		}
		return -1;
	}

	@SuppressWarnings("unchecked")
	private void resize(int size) {
		T[] newStack = (T[]) new Object[size];
		System.arraycopy(stack, 0, newStack, 0, top + 1);
		stack = newStack;
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			private int current = top;

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

			@Override
			public T next() {
				return stack[current--];
			}
		};
	}

}



队列:

接口定义:

public interface Queue<T> extends Iterable<T> {
	/**
	 * Check if the queue is empty.
	 * 
	 * @return True if the queue is empty. False otherwise.
	 */
	public boolean isEmpty();

	/**
	 * Get the size of the queue.
	 * 
	 * @return Size
	 */
	public int size();

	/**
	 * Get the head of the queue.
	 * 
	 * @return Head
	 */
	public T peek();

	/**
	 * Add an item to the queue.
	 * 
	 * @param item
	 *            Item
	 */
	public void add(T item);

	/**
	 * Poll the head of the queue.
	 * 
	 * @return Head
	 */
	public T poll();
	
	/**
	 * 
	 * Search the position of the item in the queue
	 * @param item Item
	 * @return Position of item. -1 if non-exists.
	 */
	public int search(T item);

}

链表实现:

public class LinkedListQueue<T> implements Queue<T> {
	private Node dummyHead;
	private Node tail;
	private int size;

	public LinkedListQueue() {
		dummyHead = new Node(null);
		tail = dummyHead;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public T peek() {
		if (size == 0) {
			return null;
		}
		return dummyHead.next.item;
	}

	@Override
	public void add(T item) {
		Node node = new Node(item);
		tail.next = node;
		tail = tail.next;
		size++;
	}

	@Override
	public T poll() {
		if (size == 0) {
			return null;
		}
		T item = dummyHead.next.item;
		dummyHead.next = dummyHead.next.next;
		size--;
		if(size == 0) {
			tail = dummyHead;
		}
		return item;
	}

	@Override
	public int search(T item) {
		if (size == 0 || item == null) {
			return -1;
		}
		Node current = dummyHead.next;
		int index = 0;
		while (current != null) {
			if (current.item.equals(item)) {
				return index;
			}
			current = current.next;
			index++;
		}
		return -1;
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			Node current = dummyHead.next;

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

			@Override
			public T next() {
				T item = current.item;
				current = current.next;
				return item;
			}
		};
	}

	private class Node {
		T item;
		Node next;

		Node(T item) {
			this.item = item;
		}
	}

}


数组实现:

public class ArrayQueue<T> implements Queue<T> {
	private T[] queue;
	private int head;
	private int tail;
	private int size;

	@SuppressWarnings("unchecked")
	public ArrayQueue() {
		queue = (T[]) new Object[4];
		tail = -1;
	}

	@Override
	public boolean isEmpty() {
		return size == 0;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public T peek() {
		if (size == 0) {
			return null;
		}
		return queue[head];
	}

	@Override
	public void add(T item) {
		if (tail + 1 == queue.length) {
			if (!refresh()) {
				resize(queue.length * 2);
			}
		}
		queue[++tail] = item;
		size++;
	}

	@Override
	public T poll() {
		if (size == 0) {
			return null;
		}
		T item = queue[head];
		queue[head++] = null;
		size--;
		if (size == 0) {
			head = 0;
			tail = -1;
		}
		if (queue.length > 4 && size == queue.length / 4) {
			resize(queue.length / 2);
		}
		return item;
	}

	@Override
	public int search(T item) {
		if (size == 0 || item == null) {
			return -1;
		}
		int current = head;
		while (current <= tail) {
			if (queue[current].equals(item)) {
				return current - head;
			}
			current++;
		}
		return -1;
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {
			int current = head;

			@Override
			public boolean hasNext() {
				return current <= tail;
			}

			@Override
			public T next() {
				return queue[current++];
			}
		};
	}

	@SuppressWarnings("unchecked")
	private void resize(int capacity) {
		T[] newQueue = (T[]) new Object[capacity];
		System.arraycopy(queue, head, newQueue, 0, size);
		queue = newQueue;
		head = 0;
		tail = size - 1;
	}

	private boolean refresh() {
		if (head == 0) {
			return false;
		}
		if (size >= 3 * queue.length / 4) {
			return false;
		}
		for (int i = head, j = 0; i <= tail; i++, j++) {
			queue[j] = queue[i];
		}
		head = 0;
		tail = size - 1;
		return true;
	}

}

总结:
数组实现要注意容量的变化。

实现自定义集合的Iterate:

1. Implement Iterable 接口,返回一个iterator

2. 内建类implement Iterator,实现iterator。

注意,foreach 实际是调用了iterator。

Java 不支持new generic 数组,使用cast实现。T[] array = (T[]) new Object[3];
ArrayList用的就是resizing array。LinkedList 是用的linked list。

Stack栈的特性是先入后出,Queue队列的特性是先入先出。Deque的特性是双向进出。addFirst加在头,addLast加在尾。removeFirst从头出,removeLast从尾出。

Deque作为Stack是addFirst,removeFirst。头进头出。Deque<T> stack = new ArrayDeque<T>();

Deque作为Queue是addLast,removeFirst。尾进头出。Queue<T> queue = new ArrayDeque<T>();


应用:

1. Dijkstra's two stack algorithm 迪杰斯特拉双栈法计算表达式

public static double calculate(char[] input) {
	Stack<Character> operation = new Stack<Character>();
	Stack<Double> value = new Stack<Double>();
	for (char i : input) {
		if (i == '(') {
			;
		} else if (i == '+') {
			operation.push(i);
		} else if (i == '*') {
			operation.push(i);
		} else if (i == ')') {
			char op = operation.pop();
			if (op == '+') {
				value.push(value.pop() + value.pop());
			} else if (op == '*') {
				value.push(value.pop() * value.pop());
			}
		} else {
			value.push((double) (i - '0'));
		}
	}
	return value.pop();
}
两个栈,一个存操作,一个存值。如果遇到)时,值栈弹出两个值,操作栈弹出一个操作,进行计算,结果存入值栈中。

例如 :(4+(1+2))

2

1  +

4  +

1. 遇到第一个),弹出2, 1, + 进行计算(2+1),结果存入值栈

3

4   +

2. 遇到第二个),弹出3, 4, + 进行聚散(3 + 4),结果存入值栈

7

3. 得到结果 7

2. 十进制转二进制

public static String toBinary(int num) {
	if (num == 0) {
		return "0";
	}
	Stack<Integer> result = new Stack<Integer>();
	while (num > 0) {
		result.push(num % 2);
		num /= 2;
	}
	StringBuilder sb = new StringBuilder();
	while (!result.isEmpty()) {
		sb.append(result.pop());
	}
	return sb.toString();
}

Java Stack API 的iterator(for each)是按入栈顺序next,而不是出栈顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值