1.问题
翻转栈的所有的元素,如果输入栈{1,2,3,4,5},其中1 在栈顶,翻转之后的栈为{5,4,3,2,1},5在栈顶。
2 问题分析
思路1:
首先最简单的方法就是申请一个新的栈,把原来栈中的元素依次弹出,并且压如到新的栈中,这种方法的空间复杂度高,但是简单。
思路2 :采用递归的方法
递归程序需要注意两个关键因素:递归定义和递归终止的条件。
递归定义:将当前栈的最底元素移动到栈顶,其他元素顺次下移一位,然后对不包含栈顶元素的子栈进行相同的操作。
终止条件:递归下去,直到栈为空。
比如; 在对栈1,2,3,4,5 ,进行翻转操作时。需要把栈底元素移到栈顶 5,1,2,3,4 ,然后在对不包含栈顶的元素1,2,3,4 进行翻转,变成4,1,2,3,在对不包含栈顶的元素1,2,3 进行翻转,变成3,1,2, 往复,最终变成5,4,3,2,1。
在上述翻转之前,由于栈的先后后出的原则,只能取出栈顶的元素,因此要把栈底的元素移动到栈顶,也需要递归调用。
主要的思路为: 先把不包含该栈顶元素的子栈的栈底的元素移动到子栈的栈顶,然后把栈顶的元素与子栈栈顶的元素进行交换。
3. 代码实现如下:
package Stack.ReverseStack;
import java.util.Stack;
public class ReverseStack {
private static void move_bottom_to_top(Stack<Integer> s){
if (s.empty()){
return;
}
int top1=s.peek();
s.pop();
if (!s.empty()){
move_bottom_to_top(s);
int top2=s.peek();
s.pop();
//交换栈顶元素与子栈栈顶元素
s.push(top1);
s.push(top2);
}else {
s.push(top1);
}
}
public static void revese_stack(Stack<Integer> s){
if (s.empty()){
return;
}
//把栈底元素移动到栈顶
move_bottom_to_top(s);
int top=s.peek();
s.pop();
//递归处理子栈
revese_stack(s);
s.push(top);
}
public static void main(String[] args) {
Stack<Integer> s=new Stack<>();
s.push(5);
s.push(4);
s.push(3);
s.push(2);
s.push(1);
revese_stack(s);
System.out.println("翻转后出站的顺序为;");
while (!s.empty()){
System.out.print(s.peek()+" ");
s.pop();
}
}
}
把栈底元素移到栈顶的操作时间为O(N),在翻转过程中,对每个子栈都进行了栈底元素移到栈顶的操作,因此算法的总体时间复杂度为O(N^2).
4 问题引申:
如何对栈的元素进行排序
主要思路:首先对不包含栈顶元素的子栈进行排序,如果栈顶元素的大于子栈的栈顶元素,则交换两个元素。
package Stack.ReverseStack;
import java.util.Stack;
public class ReverseStack {
private static void move_bottom_to_top(Stack<Integer> s){
if (s.empty()){
return;
}
int top1=s.peek();
s.pop();
if (!s.empty()){
move_bottom_to_top(s);
int top2=s.peek();
if (top1>top2){
s.pop();
s.push(top1);
s.push(top2);
return;
}
}
s.push(top1);
}
public static void revese_stack(Stack<Integer> s){
if (s.empty()){
return;
}
//把栈底元素移动到栈顶
move_bottom_to_top(s);
int top=s.peek();
s.pop();
//递归处理子栈
revese_stack(s);
s.push(top);
}
public static void main(String[] args) {
Stack<Integer> s=new Stack<>();
s.push(4);
s.push(6);
s.push(8);
s.push(2);
s.push(1);
revese_stack(s);
System.out.println("排序后出站的顺序为;");
while (!s.empty()){
System.out.print(s.peek()+" ");
s.pop();
}
}
}