生成所有的出栈序列 (回溯法)

来源:互联网 发布:网络电子游戏官网 编辑:程序博客网 时间:2024/04/30 08:31

给定一个入栈序列,找出所有可能的出栈序列。

入栈序列为 [1, 2, 3]
可能的出栈序列为 :
[ 3 2 1 ]
[ 2 3 1 ]
[ 2 1 3 ]
[ 1 3 2 ]
[ 1 2 3 ]


采用回溯法和递归统计所有可能的出栈序列。

  • 当所有的入栈序列已经全部入栈后,则只能出栈
  • 当栈为空时,只能进栈
  • 当仍有入栈元素且栈不为空时,可以入栈,也可以出栈

入栈 -> 递归处理下一个入栈元素 -> 恢复未入栈状态
出栈 -> 将出栈元素添加到出栈序列 -> 递归处理当前入栈元素 -> 恢复栈和出栈序列上一个的状态

#include <iostream>#include <stack>#include <vector>#include <algorithm>using namespace std;// input: 输入序列,i 表示输入到第 i 个,N 表示有 N 个输入元素; seq: 某一个输出序列; result : 存储所有的序列void GetAllSequence(const int* input, int i, const int N, stack<int> &stk, vector<int> &seq,vector<vector<int> > &result) {    if (i == N) {        // 输入序列全部入栈完毕,只能出栈。将栈中的元素添加到seq 的后面, 保存 seq        if (!stk.empty()) {            int top = stk.top();            seq.push_back(top);            stk.pop();            GetAllSequence(input, i, N, stk, seq, result); // 保持 i == N,递归地将 stk 元素复制到 seq            stk.push(top); //回溯            seq.pop_back();        } else {            result.push_back(seq); // 保存结果        }    } else {        // 对于一个输入元素,可以入栈;可以不入,弹出栈中已有元素        // 入栈        stk.push(input[i]);        GetAllSequence(input, i+1, N, stk, seq, result); // 向 i+1 递归        stk.pop(); // 回溯,恢复栈之前的状态        // 出栈        if (!stk.empty()) {            int top = stk.top(); //记录            stk.pop();            seq.push_back(top);            GetAllSequence(input, i, N, stk, seq, result); // 保持 i 不变            seq.pop_back(); // 回溯,恢复栈和序列之前的状态            stk.push(top);        }    }}int main(){    int input[] = {1,2,3}; // 输入序列    const int N = sizeof(input)/sizeof(input[0]);    vector<vector<int> > result; //保存所有序列    vector<int> seq;    stack<int> stk;    GetAllSequence(input, 0, N, stk, seq, result);    for (int i = 0; i < result.size(); i++) {        for (int j = 0; j < result[0].size(); j++) {            cout << result[i][j] << " ";        }        cout << endl;    }}
0 0