之前遇到的一道题,突然想起来,发现不会做了,想了好久,终于又想出来了,记录一下。
分析:递归的一个很厉害的作用就是能够把大事化小,小事化了。就是一个金字塔,也能化成一个小三角。从这个方向出发去思考的话,事情就比较简单了,含n个元素的栈可以看作是含n-1个元素的栈再push一个元素的结果。很容易想到把含n个元素的栈化为处理含n-1个元素的栈,最后再push第n个元素。依次递归,可以将栈化为包含1个元素的栈。此时,递归结束。再来分析第n个元素,这个元素最后要push到栈中,因此,这个元素必须得是栈底的元素。按照这个思路,必须有个函数取得栈底元素并删除栈底元素,然后递归调用自己,将n-1个元素的栈逆序,最后再push之前获得的栈底元素。最后,再实现这个取得栈底元素的函数,也需要用递归的方式。分析这个递归函数的参数:栈底元素可以通过返回值或者引用传出来,另一个参数就是这个栈。函数实现就容易了:取得栈底元素的时候,只需要取得栈顶元素,pop栈顶元素,递归调用自己获得栈底元素,push之前的栈顶元素。这个方法也是递归的经典用法。取个名字吧,就叫做:缩小规模法。c++代码如下:
缩小规模法:
int GetBottomValue(stack<int>& dataStack) { int bottomValue = 0; int topValue = 0; int size = dataStack.size(); topValue = dataStack.top(); dataStack.pop(); if (size == 1) { return topValue; } bottomValue = GetBottomValue(dataStack); dataStack.push(topValue); return bottomValue; } void ReverseStack(stack<int>& dataStack) { int bottomValue = GetBottomValue(dataStack); if (dataStack.size() != 0) { ReverseStack(dataStack); } dataStack.push(bottomValue); } void SinkTop(int depth, stack<int>& dataStack) { depth--; if (dataStack.size() < 2) { return; } int top = dataStack.top(); dataStack.pop(); int second = dataStack.top(); dataStack.pop(); dataStack.push(top); if (depth > 0) { SinkTop(depth, dataStack); } dataStack.push(second); } int main() { stack<int> dataStack; dataStack.push(1); dataStack.push(2); dataStack.push(3); dataStack.push(4); dataStack.push(5); //ReverseStack(dataStack); int size = dataStack.size(); for (int i = 1; i < size; i++) { SinkTop(size - i, dataStack); } for (int i = 0; i < size; i++) { cout << dataStack.top() << endl; dataStack.pop(); } system("pause"); }
还有一种方法:这种方法没有站在递归的角度,只是站在解决问题的角度,只不过最后实现需要用递归而已。分析要逆序一个栈,肯定就需要把栈顶的元素放到栈底,做完这步之后,发现除了栈底元素之外,这个栈很像一个更小规模的需要逆序的栈,可以再对它进行同样的移动栈顶元素到栈底的操作。依次递归,最后,就完成了栈的逆序,有点像冒泡排序,但是这里是栈顶元素下沉。并且不是下沉到栈底,而是下沉到指定的位置。下沉操作的实现也不难:可以用三个参数,一的个表示要下沉的栈顶元素值,一个表示下沉位置,一个表示栈本身。每次按照下沉位置,将栈顶元素push后,再把之前递归pop的元素出栈,依次递归就好了。也可以用两个参数实现递归函数,一个表示下沉深度,一个表示栈本身。递归交换栈顶的两个元素,直到递归深度为0,每次递归下沉一个元素,总共需要n-1此递归。
用两个参数的c++实现如下:
void SinkTop(int depth, stack<int>& dataStack)
{
depth--;
if (dataStack.size() < 2)
{
return;
}
int top = dataStack.top();
dataStack.pop();
int second = dataStack.top();
dataStack.pop();
dataStack.push(top);
if (depth > 0)
{
SinkTop(depth, dataStack);
}
dataStack.push(second);
}
int main()
{
stack<int> dataStack;
dataStack.push(1);
dataStack.push(2);
dataStack.push(3);
dataStack.push(4);
dataStack.push(5);
int size = dataStack.size();
for (int i = 1; i < size; i++)
{
SinkTop(size - i, dataStack);
}
for (int i = 0; i < size; i++)
{
cout << dataStack.top() << endl;
dataStack.pop();
}
system("pause");
}
网友评论