栈与队列

1.用栈实现队列

s1是入栈的,s2是出栈的。

入队列:直接压入s1即可

出队列:如果s2不为空,把s2中的栈顶元素直接弹出;否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素

 

2. 用队列实现栈

两个队列Q1, Q2

定义两个指针:push_temp:指向专门进栈的队列; pull_temp:指向出栈的队列

初始下:push_temp = Q1, pull_temp = Q2

入栈:直接入push_temp所指的队列即可

出栈:如果push_temp队列里元素 =1,直接出队列。否则,push_temp队列移动到pull_temp队列并仅剩一个元素,然后push_temp最后元素出队列。push_temp与pull_temp指针交换。


3. 定义栈的数据结构,实现一个能够得到栈的最小元素的函数

在该栈中,调用min,push,pop的时间复杂度都是O(1)

一个是普通的数据栈,data_stack,和另外一个min_stack辅助栈,首先在空的时候都压入两个栈,然后对于压入的序列,比较这个元素和辅助栈栈顶元素,如果小于这个栈顶那么在压入数据栈的时候也压入辅助站,否则,将辅助栈的顶部元素再次压入一次,这样保证了两个栈的大小相等,这样才能在pop的时候同步,否则在调用min以后更新候判断就比较麻烦。

 1: class MyStack {
 2:     private Stack<Integer> dataStack = new Stack<>();
 3:     private Stack<Integer> minStack = new Stack<>();
 4:     public void push(int data) {
 5:         int minData;
 6:         if (minStack.isEmpty()) {
 7:             minData = data;
 8:         } else {
 9:             minData = minStack.peek();
 10:             minData = (data < minData) ? data : minData;
 11:         }
 12:         dataStack.push(data);
 13:         minStack.push(minData);
 14:     }
 15:     public int pop() {
 16:         minStack.pop();
 17:         return dataStack.pop();
 18:     }
 19:     public int min() {
 20:         return minStack.peek();
 21:     }
 22: }


4. 判断压入弹出顺序问题

思路:遍历第二个序列,对于序列的每个元素,首先看这个元素在不在栈顶,在的话弹出;不在的话遍历第一个序列,一边遍历一边将第一个序列元素压栈,如果第一个序列没有,则证明则第二个序列的这个元素已经压进去栈了.

 1: public boolean isPopOrder(int[] pushOrder, int[] popOrder, int len) {
 2:     if (null == pushOrder || null == popOrder || len < 1) {
 3:         return false;
 4:     }
 5:     Stack<Integer> stack = new Stack<>();
 6:     int temp;
 7:     int j = 0;
 8:     for (int i = 0; i < len; i++) {
 9:         temp = popOrder[i];
 10:         if (!stack.isEmpty() && temp == stack.peek()) {
 11:             stack.pop();
 12:         } else {
 13:             for (; j < len; j++) {
 14:                 if (temp != pushOrder[j]) {
 15:                     stack.push(pushOrder[j]);
 16:                 } else {
 17:                     // 找到后终止查找
 18:                     break;
 19:                 }
 20:             }
 21:             if (j == len) {// 第一个序列里面没有,失败
 22:                 return false;
 23:             } else {
 24:                 j++;// 下次从第j++位置开始找
 25:             }
 26:         }
 27:     }
 28:     return true;
 29: } 


5. 颠倒栈

题目:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1 在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5 处在栈顶

 1: public <T> void reverse(Stack<T> stack) {
 2:     if (stack.size() == 1)
 3:         return;
 4:     T top = stack.pop();
 5:     reverse(stack);
 6:     putToBottom(stack, top);
 7: }
 8:  
 9: public <T> void putToBottom(Stack<T> stack, T o) {
 10:     if (stack.isEmpty()) {
 11:         stack.push(o);
 12:         return;
 13:     }
 14:     T top = stack.pop();
 15:     putToBottom(stack, o);
 16:     stack.push(top);
 17: }


6.写一个栈数据结构

 1: public class LinkedStack<T> {
 2:     class Node<V> {
 3:         private V data;
 4:         private Node<V> nextNode;
 5:  
 6:         public Node() {
 7:             this.data = null;
 8:             this.nextNode = null;
 9:         }
 10:  
 11:         public Node(V value, Node<V> next) {
 12:             this.data = value;
 13:             this.nextNode = next;
 14:         }
 15:  
 16:         public boolean empty() {
 17:             return data == null && nextNode == null;
 18:         }
 19:     }
 20:  
 21:     private Node<T> topNode = new Node<>();
 22:  
 23:     public void push(T value) {
 24:         topNode = new Node<T>(value, topNode);
 25:     }
 26:  
 27:     public T pop() {
 28:         if (!isEmpty()){
 29:             T result = topNode.data;
 30:             topNode = topNode.nextNode;
 31:             return result;
 32:         }else {
 33:             return null;
 34:         }
 35:     }
 36:     
 37:     public boolean isEmpty(){
 38:         if (!topNode.empty())
 39:             return false;
 40:         return true;
 41:     }
 42: }

你可能感兴趣的:(栈与队列)