这两篇博客讲得很详细:Java栈详解
C++栈详解
我总结一下:
Stack<T>mystack=new Stack<T>();//定义
public boolean isEmpty()//判断栈是否为空
public int getLength()//获取栈中元素的个数
public void push(T t)//压栈(向栈顶放入元素)
public T pop()//出栈(拿出栈顶元素,并得到它的值)
public T getHeadNext()//获取栈顶元素(未拿出)
public boolean contains(T t)//判断栈中是否包含该元素
stack< int > s; //定义
s.empty(); //如果栈为空则返回true, 否则返回false;
s.size(); //返回栈中元素的个数
s.top(); //返回栈顶元素, 但不删除该元素
s.pop(); //弹出栈顶元素, 但不返回其值
s.push(); //将元素压入栈顶
//新建
Queue<T> queue = new LinkedList<>();
//添加元素
queue.offer(T1);
//删除元素
queue.poll(T1);
//查看队首元素
queue.peek();
offer,add 区别:
一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。
这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。
poll,remove 区别:
remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。
peek,element区别:
element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。
1.栈为先进后出,队列是先进先出,所以可以使用一个栈A存储数据,在删除队列元素时将栈内所有元素倒序入另一个栈B,然后去除栈顶元素将所有元素倒入栈A。
2.java实现:
class CQueue {
Stack<Integer>ru;
Stack<Integer>chu;
public CQueue() {
ru=new Stack<Integer>();
chu=new Stack<Integer>();
}
public void appendTail(int value) {
ru.push(new Integer(value));
}
public int deleteHead() {
if(ru.empty())
return -1;
while(!ru.empty())
{
Integer tem=ru.pop();
chu.push(tem);
}
int res=chu.pop();
while(!chu.empty())
{
Integer tem=chu.pop();
ru.push(tem);
}
return res;
}
}
结果:
可以看到不高效,因为每次除去队列首元素时都进行了两次倾倒动作。
一个栈A接收元素,然后删除队首元素时,将所有元素倒入另一个栈B,去除B栈顶元素即为去除队列首元素。以后再添加元素即加入A栈顶即可,删除元素时需要看B:
class CQueue {
LinkedList<Integer> A, B;
public CQueue() {
A = new LinkedList<Integer>();
B = new LinkedList<Integer>();
}
public void appendTail(int value) {
A.addLast(value);
}
public int deleteHead() {
if(!B.isEmpty()) return B.removeLast();
if(A.isEmpty()) return -1;
while(!A.isEmpty())
B.addLast(A.removeLast());
return B.removeLast();
}
}
// 作者:jyd
// 链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/solution/mian-shi-ti-09-yong-liang-ge-zhan-shi-xian-dui-l-2/
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class CQueue {
Stack<Integer>a,b;
public CQueue() {
a=new Stack<Integer>();
b=new Stack<Integer>();
}
public void appendTail(int value) {
a.push(new Integer(value));
}
public int deleteHead() {
if(!b.empty())
{
return b.pop();
}
else if(!a.empty())
{
while(!a.empty())
{
Integer temp=a.pop();
b.push(temp);
}
return b.pop();
}
else
return -1;
}
}
第一眼看到时就想拿个int存储最小值,但是最小值去除之后再找最小值就难以操作,需要记录第二小的值。
于是我查看了题解,只需要一个辅助栈存储逆序的值即可,关键是因为栈的特性,已存在的数据位置不会改变,所以只需存储从第一个元素开始的严格逆序的元素即可。
class MinStack {
Stack<Integer>st;
Stack<Integer>helpst;
/** initialize your data structure here. */
public MinStack() {
st=new Stack<Integer>();
helpst=new Stack<Integer>();
}
public void push(int x) {
st.push(new Integer(x));
if(helpst.empty())
{
helpst.push(new Integer(x));
return;
}
if(x<=helpst.peek().intValue())
helpst.push(new Integer(x));
}
public void pop() {
int temp=st.pop();
if(temp==helpst.peek().intValue())
helpst.pop();
}
public int top() {
return st.peek().intValue();
}
public int min() {
return helpst.peek().intValue();
}
}
1.我好像没有深入理解栈与队列的特性,比如第二题中,辅助栈只需存储逆序元素即可,我还反应了好一会儿才明白;
2.编程手感要一直练才会存在。
3.参考:
java队列
java栈