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

来源:互联网 发布:销存软件排名 编辑:程序博客网 时间:2024/06/01 21:06

说明:
为了练习算法能力并记录一些解题时的思路(唯一目的),在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;}

运行效果:
to_reverse_a_stack_onlyby_recursive_and_stackOperations

阅读全文
0 0
原创粉丝点击