不用额外的空间颠倒栈你能够做到吗?

来源:互联网 发布:淘宝网上银行支付 编辑:程序博客网 时间:2024/04/27 19:41

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

分析:乍一看到这道题目,第一反应是把栈里的所有元素逐一pop出来,放到一个数组里,然后在数组里颠倒所有元素,最后把数组中的所有元素逐一push进入栈。这时栈也就颠倒过来了。颠倒一个数组是一件很容易的事情。不过这种思路需要显示分配一个长度为O(n)的数组,而且也没有充分利用递归的特性。

我们再来考虑怎么递归。我们把栈{1, 2, 3, 4, 5}看成由两部分组成:栈顶元素1和剩下的部分{2, 3, 4, 5}。如果我们能把{2, 3, 4, 5}颠倒过来,变成{5, 4, 3, 2},然后在把原来的栈顶元素1放到底部,那么就整个栈就颠倒过来了,变成{5, 4, 3, 2, 1}

接下来我们需要考虑两件事情:一是如何把{2, 3, 4, 5}颠倒过来变成{5, 4, 3, 2}。我们只要把{2, 3, 4, 5}看成由两部分组成:栈顶元素2和剩下的部分{3, 4, 5}。我们只要把{3, 4, 5}先颠倒过来变成{5, 4, 3},然后再把之前的栈顶元素2放到最底部,也就变成了{5, 4, 3, 2}

至于怎么把{3, 4, 5}颠倒过来……很多读者可能都想到这就是递归。也就是每一次试图颠倒一个栈的时候,现在栈顶元素pop出来,再颠倒剩下的元素组成的栈,最后把之前的栈顶元素放到剩下元素组成的栈的底部。递归结束的条件是剩下的栈已经空了。这种思路的代码如下:

假设我先拿int为例子吧

// ReverseStack3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <stack>
using namespace std;
/*
if(Stack.empty())
{
Stack.push(data);
}
else
{
int top=Stack.top();//放2的时候先把1弹出来
Stack.pop();
AddToButton(Stack,data);
Stack.push(top);//1放到栈里面后再把2放进去
}
*/

void AddToButton(stack<int>& Stack,int data)
{
 if (Stack.empty())
 {
  Stack.push(data);
 }
 else
 {
  int top=Stack.top();
  Stack.pop();
  AddToButton(Stack,data);
  Stack.push(top);
 }

}
void ReverseStack(stack<int>& Stack)
{
 if (!Stack.empty())
 {
  int top=Stack.top();
  Stack.pop();
  ReverseStack(Stack);
  AddToButton(Stack,top);
 }
 
}
int _tmain(int argc, _TCHAR* argv[])
{
 int a[]={1,2,3,4,5};
 stack<int> T;
 for (int i=0;i<5;i++)
 {
  T.push(a[i]);
 }
 ReverseStack(T);
 while (!T.empty())
 {
  cout<<T.top();
  T.pop();
 }
 system("pause");
 return 0;
}

 

// ReverseStack3.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <stack>using namespace std;/*if(Stack.empty()){Stack.push(data);}else{int top=Stack.top();//放2的时候先把1弹出来Stack.pop();AddToButton(Stack,data);Stack.push(top);//1放到栈里面后再把2放进去}*/void AddToButton(stack<int>& Stack,int data){if (Stack.empty()){Stack.push(data);}else{int top=Stack.top();Stack.pop();AddToButton(Stack,data);Stack.push(top);}}void ReverseStack(stack<int>& Stack){if (!Stack.empty()){int top=Stack.top();Stack.pop();ReverseStack(Stack);AddToButton(Stack,top);}}int _tmain(int argc, _TCHAR* argv[]){int a[]={1,2,3,4,5};stack<int> T;for (int i=0;i<5;i++){T.push(a[i]);}ReverseStack(T);while (!T.empty()){cout<<T.top();T.pop();}system("pause");return 0;}