只用递归和栈操作逆序一个栈

之前遇到的一道题,突然想起来,发现不会做了,想了好久,终于又想出来了,记录一下。

分析:递归的一个很厉害的作用就是能够把大事化小,小事化了。就是一个金字塔,也能化成一个小三角。从这个方向出发去思考的话,事情就比较简单了,含n个元素的栈可以看作是含n-1个元素的栈再push一个元素的结果。很容易想到把含n个元素的栈化为处理含n-1个元素的栈,最后再push第n个元素。依次递归,可以将栈化为包含1个元素的栈。此时,递归结束。再来分析第n个元素,这个元素最后要push到栈中,因此,这个元素必须得是栈底的元素。按照这个思路,必须有个函数取得栈底元素并删除栈底元素,然后递归调用自己,将n-1个元素的栈逆序,最后再push之前获得的栈底元素。最后,再实现这个取得栈底元素的函数,也需要用递归的方式。分析这个递归函数的参数:栈底元素可以通过返回值或者引用传出来,另一个参数就是这个栈。函数实现就容易了:取得栈底元素的时候,只需要取得栈顶元素,pop栈顶元素,递归调用自己获得栈底元素,push之前的栈顶元素。这个方法也是递归的经典用法。取个名字吧,就叫做:缩小规模法。c++代码如下:

缩小规模法:

int GetBottomValue(stack& 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& dataStack) { int bottomValue = GetBottomValue(dataStack); if (dataStack.size() != 0) { ReverseStack(dataStack); } dataStack.push(bottomValue); } void SinkTop(int depth, stack& 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 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& 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 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");

}

你可能感兴趣的:(只用递归和栈操作逆序一个栈)