数据结构----------堆栈、队列补充
1. 两个队列实现一个栈
- 基本思想:(总保证一个队列的数据为空)
压栈:永远将数据添加到非空队列。
弹栈:将n-1个元素出队,并添加到另外一个空的队列,然后poll第n个元素。
- 代码实现
import java.util.LinkedList; import java.util.Queue; /** * *基于两个队列实现一个栈 * @param <Item> */ public class Stack<Item> { private Queue<Item> queue1 = new LinkedList<>(); private Queue<Item> queue2 = new LinkedList<>(); /** * 添加元素,每次都往不为空的队列中添加元素 * @param item */ public void push(Item item) { if(queue1.isEmpty()) { queue2.add(item); return; } if(queue2.isEmpty()) { queue1.add(item); } } /** * 弹出一个元素 * @return */ public Item pop() { if(queue1.isEmpty() && queue2.isEmpty()) {//如果俩个队列的数据都为空,刨出异常 throw new RuntimeException("栈为空"); }else if(queue1.isEmpty()) {//如果queue1为空, //将queue2的n-1个元素添加queue1 while(queue2.size() > 1) { queue1.add(queue2.poll()); } //返回queue2的最后一个元素 return queue2.poll(); }else {//如果queue2为空 //将queue1的n-1个元素添加的哦quque2 while(queue1.size() > 1) { queue2.add(queue1.poll()); } //返回queue1的最后一个元素 return queue1.poll(); } } }
2. 两个栈实现一个队列
- 基本思想
入队:总是往第一个栈中添加数据
出队:如果第二个栈数据不为空,咱弹栈元素即出队元素;如果第二栈的数据为空 ,则将n-1个元素弹出,并添加到第二个队列,然后弹出第一个栈的最后一个元素
- 代码实现
import java.util.Stack; /** * 两个栈实现一个队列 * @author Administrator * * @param <Item> */ public class Queue<Item> { private Stack<Item> stack1 = new Stack<>(); private Stack<Item> stack2 = new Stack<>(); /** * 入队 :全部添加到第一个栈 * @param item */ public void enqueue(Item item) { stack1.push(item); } /** * 出队: * @return */ public Item dequeue() { if(stack2.size() != 0) {//如果第二个栈不为空,直接弹出 return stack2.pop(); }else if(stack1.size() != 0) {//如果第二个栈为空,第一个栈不为空 //将n-1个元素压入第二个栈 while(stack1.size() > 1) { stack2.push(stack1.pop()); } //返回第一个栈的 最后一个元素 return stack1.pop(); } else {//如果两个栈的数据 都为空 throw new RuntimeException("队列为空"); } } }
3. 实现一个能够返回最小元素的栈
设计含最小函数min()的栈,要求min、push、pop、的时间复杂度都是O(1)。min方法的作用是:就能返回是栈中的最小值。
- 基本思想
一般情况下,我们可能会这么想:利用min变量,每次添加元素时,都和min元素作比较,这样的话,就能保证min存放的是最小值。但是这样的话,会存在一个问题:如果最小的元素出栈了,那怎么知道剩下的元素中哪个是最小的元素呢?
改进思路:
这里需要加一个辅助栈,用空间换取时间。辅助栈中,栈顶永远保存着当前栈中最小的数值。具体是这样的:原栈中,每次添加一个新元素时,就和辅助栈的栈顶元素相比较,如果新元素小,就把新元素的值放到辅助栈和原栈中,如果新元素大,就把元素放到原栈中;出栈时,如果原栈跟辅助栈元素相同,都弹出,否则只弹出原栈栈顶元素
- 代码实现
import java.util.Stack; public class MinStack<Item extends Comparable<Item>> { private Stack<Item> stack1 = new Stack<>(); private Stack<Item> stackMin = new Stack<>(); /** * 添加元素 * @param item */ public void push(Item item) { if(stack1.isEmpty()) { stack1.push(item); stackMin.push(item); }else { Item minItem = stackMin.peek(); if(item.compareTo(minItem) < 0) { stackMin.push(item); } stack1.push(item); } } public Item pop() { if(stack1.isEmpty()) { throw new RuntimeException("栈为空"); } if(stack1.peek().compareTo(stackMin.peek()) == 0) { stackMin.pop(); } return stack1.pop(); } /** * 返回最小元素 * @return */ public Item min() { if(stackMin.isEmpty()) { throw new RuntimeException("栈为空"); } return stackMin.peek(); } }