您的位置:首页 > 其它

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

2015-08-09 20:45 148 查看

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

入栈序列为 [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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: