數據結構----出棧順序有效性的判斷

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及後面的比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,及後面比4小的數,現在數列爲 5,6
step 3: 數列不空,回到step 1
step 1: 當前第一個數爲 5
step 2: 5後面的比5小的數沒有,劃掉 5,現在數列爲 6
step 3: 數列不空,回到step 1
step 1: 當前第一個數爲 6
step 2: 6後面沒有比6小的數, 劃掉 5, 現在數列爲空
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
        # 通過把值改爲None, 然後去除
        out_stack_list[0] = None
        for i in [item[0] for item in smaller_items]:
            out_stack_list[i] = None
        for i in range(len(smaller_items)+1):
            out_stack_list.remove(None)
        print(out_stack_list)
    return True

測試:

In: check_out_stack(['a','b','c','d','e','f'],['d','c','e','b','f','a']) # A
['e', 'f']
['f']
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章