卡特兰数又称卡塔兰数(Catalan number),是组合数学中一个常出现在各种计数问题中出现的数列,其前几项为 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...
卡特兰数Cn满足以下递推关系 :


1.通项公式:h(n)=C(n,2n)/(n+1)=(2n)!/((n!)*(n+1)!) = C(n, 2n) - C(n +1, 2n)
卡特兰数常见的应用有出栈序列问题,可以演变出火车进站问题,次序问题等多种情况,还可应用于括号化,凸多边形的三角划分,二叉树搜索问题等很多情景
本算法在数据结构上采用队列代表固定的入栈顺序,另外创建一个队列保留各种合法顺序,以及一个必要的栈
算法利用递归思想,通过对入栈队列,结果队列以及栈内元素数目的判断作为递归相关条件,逐层累积实现模拟全部入栈顺序操作,调用后打印出所有合法序列并统计种类数
同时引申出有限栈的情形,即栈容量小于队列长度,此时不是正常的卡特兰数
package ZPutil;
import javax.swing.*;
import java.util.*;
public class Catalan {
private static int variety = 1;
public static final void CTLOutStack(ArrayDeque<Integer> from, ArrayDeque<Integer> to, Stack<Integer> s, int num) {
Stack<Integer> st = new Stack<>();
cloneStack(st, s);
ArrayDeque<Integer> inqueue = new ArrayDeque<>();
cloneQueue(inqueue, from);
ArrayDeque<Integer> out = new ArrayDeque<>();
cloneQueue(out, to);
if (num < 0 || (st.empty() && inqueue.isEmpty() && out.isEmpty())) {
return;
}
if (pushOutQueue(num, out)) return;
Stack<Integer> stcopy = new Stack<>();
cloneStack(stcopy, st);
ArrayDeque<Integer> outcopy = new ArrayDeque<>();
cloneQueue(outcopy, out);
if (!st.empty()) {
out.addLast(st.pop());
CTLOutStack(inqueue, out, st,num);
}
if (!inqueue.isEmpty()) {
stcopy.push(inqueue.poll());
CTLOutStack( inqueue, outcopy,stcopy, num);
}
}
private static boolean pushOutQueue(int num, ArrayDeque<Integer> out) {
if (out.size() == num) {
System.out.print("第"+ variety++ +"种 ");
while (!out.isEmpty()) {
System.out.print(out.pop());
}
System.out.println();
return true;
}
return false;
}
public static final void CTLOutStack(ArrayDeque<Integer> from, ArrayDeque<Integer> to, Stack<Integer> s, int num,int stackCol) {
if (s.size() == (stackCol+1)) return;
Stack<Integer> st = new Stack<>();
cloneStack(st, s);
ArrayDeque<Integer> inqueue = new ArrayDeque<>();
cloneQueue(inqueue, from);
ArrayDeque<Integer> out = new ArrayDeque<>();
cloneQueue(out, to);
if (num < 0 || (st.empty() && inqueue.isEmpty() && out.isEmpty())) {
return;
}
if (pushOutQueue(num, out)) return;
Stack<Integer> stcopy = new Stack<>();
cloneStack(stcopy, st);
ArrayDeque<Integer> outcopy = new ArrayDeque<>();
cloneQueue(outcopy, out);
if (!st.empty()) {
out.addLast(st.pop());
CTLOutStack(inqueue, out, st,num,stackCol);
}
if (!inqueue.isEmpty()) {
stcopy.push(inqueue.poll());
CTLOutStack( inqueue, outcopy,stcopy, num,stackCol);
}
}
private static void cloneStack(Stack<Integer> stack, Stack<Integer> stack1) {
for (int i :
stack1) {
stack.push(i);
}
}
private static void cloneQueue(ArrayDeque<Integer> deque, ArrayDeque<Integer> deque1) {
for (int i :
deque1) {
deque.addLast(i);
}
}
}
更多可以参考我的GitHub