栈的数学性质:n个不同元素入栈,出栈元素不同排列的个数的推导,卡特兰数(明安图数)的推导

前言:重在记录,可能出错。
这部分内容借鉴了网络上的一些内容。如:什么是卡特兰数?怎么理解出栈顺序有多少种?(递推式的构造)

一、结论

先说结论,设n个不同元素入栈,出栈元素不同排列的个数为\({f \left( n \right) }\),则\({f \left( n \right) }\)符合以下规律:

1. $ \color{red}{f \left( n \left) =\frac{{1}}{{n+1}}C\mathop{{}}\nolimits_{{\text{ }2n}}^{{\text{ }\text{ }n}}\right. \right. }$

2. \(\color{red}{f \left( n \left) ={\mathop{ \sum }\limits_{{i=1}}^{{n}}{f \left( i-1 \left) *f \left( n-i \right) \right. \right. }}\right. \right. }\)

3.\(\color{red}{f \left( n+1 \left) =\frac{{4n+2}}{{n+2}}f \left( n \right) \right. \right. }\)

二、推导

1.建立x,y平面直角坐标系。

  假设一只小蚂蚁从原点(0,0)出发,将入栈看作向右移动一,出栈看作向上移动一。

  当n个不同元素全部入栈、出栈后,有n次入栈和n次出栈,相当于小蚂蚁爬到(n,n)位置。

  显而易得的,小蚂蚁共有\(\color{red}{C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n}}}\)种不重复的前进路线(小蚂蚁共需移动2n次,选择其中的n次为向右移动一,则剩下的n次为向上移动一)。

  分析,因为栈的特点是只允许在一端进行插入和删除,所以在执行出栈操作时,必须保证栈里存在元素,否则就会抛出栈空异常。即每一步操作,都需要保证此时出栈操作总数≤入栈操作总数。

  反映到坐标系上,即小蚂蚁不能越过y=x线或者不能碰到y=x+1线。

  显而易得的,对于会抛出异常的输出序列,当其首次抛出异常时,恰好首次出现入栈次数为m,出栈次数为m+1,剩余的入栈次数为n-m,出栈次数为n-m-1,后面的路线有\({C\text{ }\mathop{{}}\nolimits_{{2n-2m-1}}^{{n-m}}}\)种。

  \({C\text{ }\mathop{{}}\nolimits_{{2n-2m-1}}^{{n-m}}}\),这是在2n-2m-1次操作中,选取n-m次为入栈操作的意思,显而易得的,这个组合数也可以表示在2n-2m-1次操作中,选取n-m次为出栈操作的意思。将n-m次入栈向右移动一,换成n-m出栈向上移动一,反映到坐标系,即将小蚂蚁首次碰到y=x+1后的路线关于y=x+1作对称。如下图:



  小蚂蚁从(0,0)碰到y=x+1到终点(n,n)就相当于从(0,0)到终点(n-1,n+1)。因此,小蚂蚁所有碰到y=x+1的到(n,n)的路线数就相当于到(n-1,n+1)的路线数,即\(\color{red}{C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n-1}}}\)种。

  小蚂蚁从(0,0)到终点(n,n)且不碰到y=x+1的路线有

\[\begin{array}{*{20}{l}}{C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n}}\text{ }-\text{ }C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n-1}}}\\{=\frac{{ \left( 2n \left) !\right. \right. }}{{n!n!}}\text{ }-\text{ }\frac{{ \left( 2n \left) !\right. \right. }}{{ \left( n-1 \left) ! \left( n+1 \left) !\right. \right. \right. \right. }}}\\{=\frac{{ \left( 2n \left) !\right. \right. }}{{n!n!}}\text{ }-\text{ }\frac{{n}}{{n+1}}\frac{{ \left( 2n \left) !\right. \right. }}{{ \left( n \left) ! \left( n \left) !\right. \right. \right. \right. }}}\\{= \left( 1-\frac{{n}}{{n+1}} \left) \frac{{ \left( 2n \left) !\right. \right. }}{{n!n!}}\right. \right. }\\{=\frac{{1}}{{n+1}}C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n}}}\end{array}
\]

  综上,设n个不同元素进栈,出栈元素不同排列的个数为\({f \left( n \right) }\),则\(\color{red}{{f \left( n \right) }=\frac{{1}}{{n+1}}C\text{ }\mathop{{}}\nolimits_{{2n}}^{{n}}}\)。


2.假设n个不同元素为\({a\mathop{{}}\nolimits_{{1}}\text{ }a\mathop{{}}\nolimits_{{2}} \cdots a\mathop{{}}\nolimits_{{n}}}\),考虑最后一个出栈的元素是谁,是\({a\mathop{{}}\nolimits_{{i}}}\)。

  \({a\mathop{{}}\nolimits_{{i}}}\)最后一个出栈,说明\({a\mathop{{}}\nolimits_{{i}}}\)始终在栈底,即当到\({a\mathop{{}}\nolimits_{{i}}}\)的时候,\({a\mathop{{}}\nolimits_{{1}}\text{ }\text{ }a\mathop{{}}\nolimits_{{2}} \cdots a\mathop{{}}\nolimits_{{i-1}}}\)全部完成了正常的入栈、出栈,给\({a\mathop{{}}\nolimits_{{i}}}\)留了一个空栈,这样的序列有\({f \left( i-1 \right) }\)种;

  \({a\mathop{{}}\nolimits_{{i}}}\)进入栈底后,不动,此时的栈相当于底厚了一点的“空栈”,等\({a\mathop{{}}\nolimits_{{i+1}}\text{ }\text{ }a\mathop{{}}\nolimits_{{i+2}} \cdots a\mathop{{}}\nolimits_{{n}}}\)全部先完成正常的入栈、出栈,序列有\({f \left( n-i \right) }\)种。总共有\({f \left( i-1 \left) *f \left( n-i \right) \right. \right. }\)种序列。

  综上,i的取值为1~n的正整数,所以\(\color{red}{f \left( n \left) ={\mathop{ \sum }\limits_{{i=1}}^{{n}}{f \left( i-1 \left) *f \left( n-i \right) \right. \right. }}\right. \right. }\)


3.我们先算出当n=1,n=2,n=3,n=4,n=5时的\({f \left( n \right) }\)的值,再总结规律,\({f \left( 1 \left) =1,f \left( 2 \left) =2,f \left( 3 \left) =5,f \left( 4 \left) =14,f \left( 5 \left) =42\right. \right. \right. \right. \right. \right. \right. \right. \right. \right. }\)这怎么看规律?就用眼珠子瞪,很简单啊,知道答案,硬凑就行了。!^.^!

\[{\begin{array}{*{20}{l}}{\frac{{f \left( 2 \right) }}{{f \left( 1 \right) }}=\frac{{2}}{{1}},\frac{{f \left( 3 \right) }}{{f \left( 2 \right) }}=\frac{{5}}{{2}},\frac{{f \left( 4 \right) }}{{f \left( 3 \right) }}=\frac{{14}}{{5}},\frac{{f \left( 5 \right) }}{{f \left( 4 \right) }}=\frac{{42}}{{14}}}\\{\frac{{f \left( 2 \right) }}{{f \left( 1 \right) }}=\frac{{6}}{{3}},\frac{{f \left( 3 \right) }}{{f \left( 2 \right) }}=\frac{{10}}{{4}},\frac{{f \left( 4 \right) }}{{f \left( 3 \right) }}=\frac{{14}}{{5}},\frac{{f \left( 5 \right) }}{{f \left( 4 \right) }}=\frac{{18}}{{6}}}\\{\frac{{f \left( n+1 \right) }}{{f \left( n \right) }}=\frac{{6+4 \left( n-1 \right) }}{{n+2}}=\frac{{4n+2}}{{n+2}}}\\{f \left( n+1 \left) =\frac{{4n+2}}{{n+2}}f \left( n \right) \right. \right. }\end{array}}
\]

  综上,$\color{red} {f\left( n+1 \left) =\frac{{4n+2}}{{n+2}}f \left( n \right) \right. \right.} $

栈的数学性质:n个不同元素入栈,出栈元素不同排列的个数的推导,卡特兰数(明安图数)的推导的更多相关文章

  1. 设计一个栈,设计一个max()函数,求当前栈中的最大元素

    #include <iostream> using namespace std; #define MAXSIZE 256 typedef struct stack { int top; i ...

  2. flask 源码专题(三):请求上下文和应用上下文入栈与出栈

    1.请求上下文和应用上下文入栈 # 将ctx入栈,但是内部也将应用上下文入栈 ctx.push() def push(self): # 获取到的 top == ctx top = _request_c ...

  3. JVM字节码之整型入栈指令(iconst、bipush、sipush、ldc)

    官网:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html 原文地址:http://www.linmuxi.com/2016/02 ...

  4. [置顶] 栈/入栈/出栈顺序(c语言)-linux

    说明: 1.栈底为高地址,栈顶为低地址. 2.入栈顺序:从右到左. 解释1:栈在内存中的结构 [注:0x00 到 0x04之间间隔4个地址] 入栈:指针先指向0x10,从高地址向低地址方向填数值,最终 ...

  5. 003-整型入栈指令(iconst、bipush、sipush、ldc)

    一.概述 官网:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html参考地址:http://www.linmuxi.com/201 ...

  6. Internet 校验和的数学性质

    Internet 校验和(Checksum)仅计算头部的正确性,这一点很重要,这意味着 IP 协议不检查 IPv4 packet 有效载荷部分的数据正确性.为了保证有效载荷部分的正常传输,其他协议必须 ...

  7. n个元素的入栈顺序有多少种出栈顺序?

    问题:w1.w2.w3.w4.w5,5个元素将会按顺序入栈,求出栈顺序有多少种情况. 先写一下结论方便记忆: 1个元素:1种 2个元素:2种 3个元素:5种 4个元素:14种 5个元素:42种 简单的 ...

  8. 问题-栈S最多能容纳4个元素,现有6个元素按A、B、C、D、E、F顺序进栈,问可能的出栈顺序。

    住栈的特性:对于取出栈内元素每次只能从栈顶开始取(后进先出(栈满时,只能先出后进)) 由于栈内只能容纳4个元素: 所以 E F不可能第一个出栈: 当栈内少于四个元素时 既可以选择进栈,也可以选择出栈 ...

  9. C语言数据结构-链式栈的实现-初始化、销毁、长度、取栈顶元素、查找、入栈、出栈、显示操作

    1.数据结构-链式栈的实现-C语言 //链式栈的链式结构 typedef struct StackNode { int data; struct StackNode *next; } StackNod ...

  10. C语言数据结构-栈的实现-初始化、销毁、长度、取栈顶元素、查找、入栈、出栈、显示操作

    1.数据结构-栈的实现-C语言 #define MAXSIZE 100 //栈的存储结构 typedef struct { int* base; //栈底指针 int* top; //栈顶指针 int ...

随机推荐

  1. TCP协议三握四挥、socket模块

    目录 传输层之TCP与UDP协议 应用层 socket模块 socket代码简介 代码优化 半连接池的概念 传输层之TCP与UDP协议 用于应用程序之间的通信 TCP与UDP都是用来规定通信方式的 ​ ...

  2. JavaScript:函数:函数的参数

    声明函数的时候,有个括号,这里面可以加上函数的参数,这些参数,我们叫做形参(形式参数): 此时这些参数,也是已经声明了的变量,只是还没有赋值而已. 也可以不加,取决于函数的逻辑.如果函数需要从外部传进 ...

  3. 一个实现单线程/多线程下代码调用链中传递数据的处理类: CallContext(LogicalSetData,LogicalGetData),含.net core的实现

    详情请参考原文:一个实现单线程/多线程下代码调用链中传递数据的处理类: CallContext

  4. Java求值策略

    为什么说Java不存在引用传递? 在Java语言中,存在两种数据类型,一种是基本类型,如int.byte等8种基本类型,一种是引用类型,如String.Integer等.这两种数据类型区别就在于,基本 ...

  5. NetCore模型绑定之FromBodyFromUriFromQueryFromRoute

    title: .Net Core模型绑定之FromBody.FromUri.FromQuery.FromRoute categories: 后端 date: 2022-10-29 17:21:11 t ...

  6. [WPF]将方法设为弃用

    [System.Obsolete("这是一条提示信息,表示这个方法弃用了,使用此方法会有一条Warning信息")] private void SaveDataMessage(Sa ...

  7. [LeetCode]爬楼梯

    题目 假设你正在爬楼梯.需要 n 步你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 解释: ...

  8. Linux 驱动像单片机一样读取一帧dmx512串口数据

    硬件全志R528 目标:实现Linux 读取一帧dmx512串口数据. 问题分析:因为串口数据量太大,帧与帧之间的间隔太小.通过Linux自带的读取函数方法无法获取到 帧头和帧尾,读取到的数据都是缓存 ...

  9. VUE Angular通用动态列表组件-亦可为自动轮播组件-02-根据数据量自动横向滚动,鼠标划入停止滚动

    本文为横向轮播,纵向轮播/动态列表组件请戳---- 代码是angular的,稍微改改就可以放入Vue项目里,差别不大哟 以下代码可以根据实际情况自行调整 父组件html <app-scroll- ...

  10. 实操记录之-----Ant Design of Vue 增强版动态合并单元格,自动根据数据进行合并,可自定义横纵向合并

    前几天搞了个简易版的动态合并单元格 但是需求有变化,就只能稍微改改了~~ 欢迎路过的各位大佬指出我代码的问题~~~~ 另: 代码执行效率不是很高,如果需要大量渲染更多数据建议可以直接使用原生 < ...