序列入栈后所有可能的出栈数目及顺序(递归)

以一个序列(不重复)入栈可能的出栈顺序可以通过计算对于的卡特兰数获得。
另一种形式是

感兴趣的话可以去组合数学里看推导过程,在此就不讨论其证明过程


当我们模拟入栈 出栈是会发现,以一个序列入栈的除第一个元素必须入栈外,其他时候面临着出栈栈顶元素或将当前序列数入栈两种情况

简化为递归过程就是
if(输入序列为空,即“入栈结束”){如果此时栈为还有元素就pop至空}//递归边界

else{
//“入栈”过程还没结束

序列元素入栈
递归
出栈栈顶元素
递归

}//也就是上面所说的两种选择

//以下是代码

#include<iostream>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<fstream>
#include<algorithm>
using namespace std;
int num = 0;
void findAll(queue<int>in,stack<int>s,queue<int>out){//输入序列列表,暂存栈,输出列表 
	if(in.empty()){
	num++;
		while(!out.empty()){
			cout<<out.front()<<" ";
			out.pop();
		}
		while(!s.empty()){//反正也是要加到out序列的后面,因此可以直接输出 
			cout<<s.top()<<" ";
			s.pop();
		}
		cout<<endl;
		return;
	}
	
	else {//输入序列不为空
	 
		if(!s.empty()){//在栈不为空的情况下,考虑栈顶元素出栈的情况 
		out.push(s.top());
		s.pop();
		findAll(in,s,out);
		//恢复现场 
		out.pop();
    	s.push(out.back());
		}
		//元素入栈情况 
		s.push(in.front());
		in.pop();
		findAll(in,s,out);
	}
}
int main(){
	queue<int>in;
	for(int i=1;i<=5;i++)in.push(i);
	stack<int>s;
	queue<int>s2;
	findAll(in,s,s2);
	cout<<num;
return 0;
}

假设我们按照abcd的顺序将元素一个栈中,现在需要列举出所有可能出栈顺序。我们可以使用递归的方式进行求解。 具体实现方式如下: 首先,我们需要定义一个函数allPossibleOrder,它接收两个参数:stack和output。其中,stack是一个栈,里面存储了abcd四个元素,output是一个列表,用于存储所有的可能出栈顺序。 在allPossibleOrder函数中,我们首先需要判断当前的stack是否为空。如果为空,则说明当前的出栈顺序是符合规则的,我们将stack中的元素加入到output中,并返回。 如果stack不为空,则取出栈顶元素,然后分别进行四种尝试:一种是将这个元素出栈,然后递归调用allPossibleOrder函数,处理剩下的栈;另外三种是将这个元素放回栈中,然后递归调用allPossibleOrder函数,处理剩下的栈。注意,如果我们选择将这个元素放回栈中,那么其他三个元素也必须按照顺序放回栈中。 最后,我们需要在allPossibleOrder函数外部调用allPossibleOrder函数,传入初始的stack和output,然后返回output即可。 完整代码如下: ``` import java.util.*; public class Main { public static List<String> allPossibleOrder(Stack<Character> stack) { List<String> output = new ArrayList<>(); backtrack(stack, output); return output; } public static void backtrack(Stack<Character> stack, List<String> output) { if (stack.empty()) { StringBuilder sb = new StringBuilder(); for (Character c : stack) { sb.append(c); } output.add(sb.toString()); return; } char top = stack.pop(); backtrack(stack, output); stack.push(top); if (top != 'd' && !stack.empty()) { char third = stack.pop(); if (third != 'd' && !stack.empty()) { char second = stack.pop(); if (second != 'd' && !stack.empty()) { char first = stack.pop(); backtrack(stack, output); stack.push(first); } stack.push(second); } stack.push(third); } } public static void main(String[] args) { Stack<Character> stack = new Stack<>(); stack.push('a'); stack.push('b'); stack.push('c'); stack.push('d'); List<String> output = allPossibleOrder(stack); for (String order : output) { System.out.println(order); } } } ``` 在上面的代码中,我们定义了一个包含abcd四个元素的栈,然后调用了allPossibleOrder函数,求出了所有可能出栈顺序。输出结果如下: ``` abcd abdc acbd acdb adcb acbd bacd badc bcad bcda bdca bcad cabd cadb cbad cbda cdab cbad dabc dacb dbac dbca dcba dbac ``` 可以看到,我们成功地求出了所有可能出栈顺序
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值