当前课程知识点:数据结构(上) > 第四章 栈与队列 > (c3)栈应用:栈混洗 > 04C3-4 算法
关于这个问题
knuth在他的the art of computer programming中
已经给出了正面的解答
他指出 其实我们所说的禁形
不仅是个必要条件
而且确实也是个充分条件
if and only if是个充要条件
具体来说 一个排列permutation
如果确实是一个栈混洗的话
那么充要条件就是
其中不包含这种312的模式
在我们教材配套的习题解析中
第4-3题也对此作了讨论
在这里 我们不妨把证明过程忽略掉
当然这样一个结论
可以直接导出一个对应的算法
也就是说 我们去不断地枚举
所有的i j和k的组合
当然反过来也很遗憾
不难看出 这样一个算法的复杂度
将高达n的立方
我们是不能接受的
实际上 进一步地
我们还可以将这样一个判别的依据
作以简化
具体来说 我们只要逐一地去检查
每一对互异的i和j
只要在排列中不会出现
j+1、i以及j这样的一个模式
我们同样可以把它当做一个
判断栈混洗的充要条件
关于这个性质的证明
大家同样可以去参考习题4-3
同样地 这样一个改进以后的结论
可以直接导致一个新的甄别算法
因为这个算法需要枚举
所有的互异元素对
所以它也需要高达n平方的时间
所以它的时间复杂度也将高达n平方
这样的效率也同样难以令我们满意
实际上 借助栈结构
我们完全可以实现一个
线性时间的甄别算法
这个算法的思想也非常的简单
也就是完全按照栈混洗的定义
引入三个栈
并且通过对栈混洗过程的模拟
以一种验证的方式来判别某一个排列
是否的确为栈混洗
具体地 对于输出序列中的任何一个元素
我们都采用一种贪心的原则
以S为中介 将其从A转移至B中
只要这个贪心的过程能够持续进行
并最终将所有的元素顺利地从A转入B中
那么我们就可以判断它是一个栈混洗
反之 每次通过pop操作
试图从S中弹出当前的元素时
如果S已经变空
或者要弹出的元素 虽然在S中存在
但却非最顶端的元素
我们都可以立即判断这个栈混洗是非法的
我们将这样一个算法的具体实现
留给大家作为编程习题
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)计算
--演示
--(a)计算--作业
-(b)计算模型
-(b)计算模型--作业
-(c)大O记号
-(c)大O记号--作业
-(d)算法分析
-(d)算法分析--作业
-(e)迭代与递归
-(e)迭代与递归--作业
-(xc)动态规划
-- 演示
-(xc)动态规划--作业
-本章测验--作业
-(a)接口与实现
--02A-5 复制
-(a)接口与实现--作业
-(b)可扩充向量
-(b)可扩充向量--作业
-(c)无序向量
--02C-1 概述
--02C-3 插入
--02C-6 查找
--02C-8 遍历
-(c)无序向量--作业
-(d1)有序向量:唯一化
-(d1)有序向量:唯一化--作业
-(d2)有序向量:二分查找
-(d2)有序向量:二分查找--作业
-(d3)有序向量:Fibonacci查找
-(d3)有序向量:Fibonacci查找--作业
-(d4)有序向量:二分查找(改进)
-(d4)有序向量:二分查找(改进)--作业
-(d5)有序向量:插值查找
-第二章 向量(下)--(d5)有序向量:插值查找
-(e)起泡排序
--02E-2 改进
--02E-3 反例
-(e)起泡排序--作业
-(f)归并排序
-(f)归并排序--作业
-本章测验--作业
-(a)接口与实现
--03A-4 实现
-(a)接口与实现--作业
-(b)无序列表
--03B-2 查找
-(b)无序列表--作业
-(c)有序列表
--03C-3 查找
-(c)有序列表--作业
-(d)选择排序
--03D-1 构思
--03D-2 实例
--03D-3 实现
--03D-4 推敲
--03D-6 性能
-(d)选择排序--作业
-(e)插入排序
--03E-1 经验
--03E-2 构思
--03E-3 对比
--03E-4 实例
--03E-5 实现
-(e)插入排序--作业
-(xd)习题辅导:LightHouse
-本章测验--作业
- (a)栈接口与实现
--04A-1 栈
--04A-2 实例
--04A-3 实现
- (a)栈接口与实现--作业
-(c1)栈应用:进制转换
-第四章 栈与队列--(c1)栈应用:进制转换
-(c2)栈应用:括号匹配
-(c2)栈应用:括号匹配--作业
-(c3)栈应用:栈混洗
-第四章 栈与队列--(c3)栈应用:栈混洗
-(c4)栈应用:中缀表达式求值
-(c4)栈应用:中缀表达式求值--作业
-(c5)栈应用:逆波兰表达式
-第四章 栈与队列--(c5)栈应用:逆波兰表达式
-(d)队列接口与实现
--04D-1 接口
--04D-2 实例
--04D-3 实现
-第四章 栈与队列--本章测验
-(a)树
--05A-1 动机
--05A-2 应用
-(a)树--作业
-(b)树的表示
--05B-2 父亲
--05B-3 孩子
-第五章 二叉树--(b)树的表示
-(c)二叉树
-(c)二叉树--作业
-(d)二叉树实现
-(d)二叉树实现--作业
-(e1)先序遍历
-(e1)先序遍历--作业
-(e2)中序遍历
-第五章 二叉树--(e2)中序遍历
-(e4)层次遍历
-第五章 二叉树--(e4)层次遍历
-(e5)重构
-(e5)重构--作业
-本章测验--作业
-(a)概述
-(a)概述--作业
-(b1)邻接矩阵
-(b1)邻接矩阵--作业
-(c)广度优先搜索
--06C-2 策略
--06C-3 实现
--06C-5 实例
-(c)广度优先搜索--作业
-(d)深度优先搜索
--06D-1 算法
--06D-2 框架
--06D-3 细节
-(d)深度优先搜索--作业
-第六章 图--本章测验