您的位置:首页 > 其它

如何仅用递归函数和栈操作逆序一个栈

2017-10-08 22:56 260 查看
说明:

为了练习算法能力并记录一些解题时的思路(唯一目的),在CSDN博客建立了一个【程序员代码面试指南】的类别,其中所有题目均来自左老师的书《程序员代码面试指南》,所有的智慧结晶来自可爱的左老师,我只是把原书中的Java代码改用c++实现(因为本人只会一点点c++),并尽量给出含main函数的完整测试代码。

题目来源:《程序员代码面试指南》-第一章-栈与队列-如何仅用递归函数和栈操作逆序一个栈

题目描述:

一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。将这个栈转置后,从栈顶到栈底分别是1、2、3、4、5,也就是现实栈中元素的逆序,但是只能用递归函数来实现,不能用其他数据结构。

思考:

栈(stack) 是一个先进后出(FILO)的数据结构,栈操作只能得到栈顶元素(stack.top())或者弹出栈顶元素(stack.pop()),无法直接获取栈底元素。由于要使用递归函数,我们很容易可以想到:如果有一个函数A,可以先帮我们把栈底的元素出来,再使用递归函数B逆转剩下的栈(即已经移除栈底元素的栈),假设剩下的栈已经逆转完毕,那么我们只要把利用函数A取出的栈底元素再push进栈即可。那么这个函数A就至关重要了,想一下,这个可以返回移除栈底元素的函数(只实现这一个功能,栈剩余的元素顺序不变),是不是必须也是一个递归函数呢?答案是肯定的。

什么时候需要用递归(recursive)? 假如一件事情环环相扣,而每个环节你需要下个环节给你答案你才能完成这个环节,那么你需要一直走下去,直到走到最初的那一扇门,这扇门的答案直接就可以拿到(return),于是你拿到答案后返回上一层的门,在这一层拿到上上层门的通行证再继续返回,就这样逐层返回,直到走出递归。

递归函数A:将栈底元素返回并移除。

递归函数B:逆序一个栈,即题目要求实现的函数。

完整代码:

#include<iostream>
#include<stack>
using namespace std;

void traverse(stack<int> stack) {
while(!stack.empty()) {
int i = stack.top();
stack.pop();
cout << i << endl;
}
return;
}

//递归函数A:将栈底元素返回并移除
int getAndRemoveLastElement(stack<int> &stack) {
int result = stack.top();
stack.pop();
if(stack.empty()) {
return result;
}
else {
int last = getAndRemoveLastElement(stack);
stack.push(result);
return last;
}
}

//递归函数B:逆序一个栈,即题目要求实现的函数
void reverse(stack<int> &stack) {
if(stack.empty()) {
return;
}
int i = getAndRemoveLastElement(stack);
reverse(stack);
stack.push(i);
}

int main(int argc, char const *argv[])
{
stack<int> stack;
for(int i = 0; i < 5; ++i) {
stack.push(i);
}
cout << "before reverse:" << endl;
traverse(stack);

reverse(stack);
cout << "after reverse:" << endl;
traverse(stack);
return 0;
}


运行效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归