数据结构----出栈顺序有效性的判断

1 问题描述

问题1:若元素 a,b,c,d,e,f 顺序进栈, 则不准许的出栈顺序是
A. d,c,e,b,f,a    B. c,b,d,a,e,f    C. b,c,a,e,f,d    D. a,f,d,e,c,b

答案:D

2 解法描述与分析

2.1 问题的解法

1,2,3,4,5,6… 分别对应着 a,b,c,d,e,f…, 对问题1我们有以下算法

Algorithm 1 判断出栈顺序有效性算法
step 1: 记第一个数为M。
step 2: 然后在后面的数中检查比M小的数(可以没有)是否是按逆序排列,如果是则把M划掉,否则当前数列不是一个有效的出栈序列并退出判断流程。
step 3: 数列是否为空,如果不空则回到step1, 否则当前数列为有效出栈顺序并结束判断流程。

例如对于选项 A. d,c,e,b,f,a 其对应的数列为 4,3,5,2,6,1
step 1: 找到当前第一个数为4
step 2: 4后面的比4小的数为 3,2,1,为逆序排列,划掉4,现在数列为 3,5,2,6,1
step 3: 数列不空,回到step 1
step 1: 当前第一个数为 3
step 2: 3 后面的数按逆序排列, 划掉 3,现在数列为 5,2,6,1
step 3: 数列不空, 回到step 1
step 1: 当前第一个数为 5
step 2: 5后面的比5小的数按逆序排列,划掉 5,现在数列为 2,6,1
step 3: 数列不空,回到step 1
step 1: 当前第一个数为 2
step 2: 2 后面比2 小的数按逆序排列,划掉 2, 现在数列为 6,1
step 3: 回到step 3
step 1: 当前第一个数为 6
step 2: 6后面比6小的数按逆序排列, 划掉 6, 现在数列为 1
step 3: 当前数列不空回到 step 1
step 1: 当前第一个数为 1
step 2: 1后面没有数,划掉 1
step 3: 数列为空,则当前为有效的出栈顺序

对于选项 D, 简化一下算法运行格式,可得
1,6,4,5,3,2 —> 6,4,5,3,2 —> 由于比6 小的 4,5 没有逆序排列,所以该序列不是有效的出栈序列。

2.2 算法分析

首先回顾一下栈的定义,栈是 先进后出(FILO) 的线性结构。这里用反证明来证明算法的有效性。令 1,2,3,…,n分别代表n个依次入栈的元素的序号,即序号为1的第一个入栈,序号为n的最后一个入栈,出栈顺序未知。假设当第 m 个元素出栈时,且比第 m 个元素小的元素第 i,j,… (i < j < … ) 个元素尚未出栈,如果 i 比 j 先出栈,则按照栈的FILO 性质, i 比 j 后进栈,但这与前面的对序号的解释相矛盾。则第 m 个元素出栈时,序号比 m 小的元素的出栈顺序一定按元素序号逆序进行,即 序号大的先出栈。

3 算法的程序实现

3.1 Python 实现
def check_out_stack(in_stack_list, out_stack_list):
    item_dict = {v:i for i,v in enumerate(in_stack_list)}
    while len(out_stack_list) > 1:
        first_item = out_stack_list[0]
        # 获取比 first_item 小的的元素
        smaller_items = [(i+1,v,item_dict[v]) for i,v in enumerate(out_stack_list[1:]) if v < first_item]
        index = [item[2] for item in smaller_items]
        for i in range(len(index) - 1):
            if index[i] - index[i+1] < 0:
                return False
        # 去除第一个元素
        out_stack_list = out_stack_list[1:]
        print(out_stack_list)
    return True

测试:

In: check_out_stack(['a','b','c','d','e','f'],['d','c','e','b','f','a']) # A
['c', 'e', 'b', 'f', 'a']
['e', 'b', 'f', 'a']
['b', 'f', 'a']
['f', 'a']
['a']
Out: True

In:  check_out_stack(['a','b','c','d','e','f'],['a','f','d','e','c','b']) # D
['f', 'd', 'e', 'c', 'b']
Out: False
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值