檢查給定排列可否由棧得到

2021-08-19 21:54:27 字數 3173 閱讀 9904

設計乙個演算法,檢查給定排列可否由棧得到。在回答yes時,演算法應同時輸出相應的操作序列。在你的演算法中,除了read、print、push和pop,你可以利用is - empty(s),測試棧s是否為空

棧(stack)是先進先出(fifo - fisrt in first out)型的資料結構,具有這樣的性質:在棧中某成員之前進棧,且在其之後出棧的元素,在出棧時的順序必然是進棧時的逆序。舉例說明,若有進棧序列1,2,3,顯然1,2在3進棧之前進棧。若3先於1和2出棧,則出棧序列中,2必然排在1之前,因為這是它們進棧順序的倒置。因此進棧序列為1,2,3時,是不可能出現3,1,2這樣的出棧序列的。

所謂的進棧和出棧序列,並不是連續的。初學者直覺上可能會理解為,當所有成員進棧以後才會出棧,那麼進棧和出棧序列就是固定的。實際上,進棧和出棧時交錯進行的。我們所說的「進棧序列」,是指在棧的進出序列之中剔除出棧的資訊所排成的序列。例如,有序列1 in, 2 in, 2 out, 3 in, 3 out, 1 out,則進棧序列為1,2,3,出棧序列為2,1,3。

因此,檢查給定排列是否可由棧得到,人工方法可做如下檢驗:對於出棧序列的每乙個元素,都需要檢視在其之後出棧,且在其之前進棧的成員(很繞),它們的出棧序列必須是進棧序列的倒序。

還是舉個例子,若有進棧序列1,2,3,4,5,則出棧序列2,5,4,3,1是可能的。檢查如下:

檢視元素2,在其之前進棧的元素為1,在其之後出棧的元素為5,4,3,1,兩者都符合的元素為1,由於只有乙個元素,因此滿足要求;

檢視元素5,在其之前進棧的元素為1,2,3,4,在其之後出棧的元素為4,3,1,兩者都符合的元素為4,3,1,且這三者的出棧順序是進棧順序的倒置,因此滿足要求;

檢視元素4,在其之前進棧的元素為1,2,3,在其之後出棧的元素為3,1,兩者都符合的元素為3,1,且這兩者的出棧順序是進棧順序的倒置,因此滿足要求;

檢視元素3,在其之前進棧的元素為1,2,在其之後出棧的元素為1,兩者都符合的元素為1,由於只有乙個元素,因此滿足要求;

檢視元素1,在其之前進棧的元素為1,2,3,4,5,在其之後無元素出棧,沒有兩者都符合的元素,不必進行順序檢驗,因此滿足要求;

符合上述進出棧條件的操作序列為1 in, 2 in, 2 out, 3 in, 4 in, 5 in, 5 out, 4 out, 3 out, 1 out.

演算法執行的模式如下:

檢查排列是否可由棧得到:給定某個1~n的序列,從第乙個元素開始,遍歷其後的元素,對於每個小於其的元素,檢驗它們是否是降序排列的。

回答yes時輸出相應的操作序列:檢查棧頂元素,是否是出棧序列所需的下乙個元素,若是,則從棧中取出該元素並輸出它,若不是,將乙個元素壓入棧,然後再檢查棧頂元素是否滿足要求。當棧和入棧佇列均為空,或者入棧佇列已經為空,但給定序列仍未檢查完畢時,退出迴圈。若待檢驗序列遍歷完畢時,棧也已清空,則該排列可由棧得到。反之則不可以。事實上,1和2兩個問題可以一併解決。

def

checkstack

(s):

# 檢查乙個序列是否可由棧得到,是則返回true,否則返回false。函式入參為待檢驗序列,型別為list,

defpop

(stack):

# 定義出棧操作,若棧為空則返回提示,若不為空則返回棧頂元素

node = len(stack)

if(node == 0):

print('棧為空')

return

else:

pop = stack[node - 1]

del stack[node - 1]

return pop

defpush

(element, stack):

# 定義入棧操作,將element壓入stack中,並返回棧頂指標(此處為list的角標)

node = len(stack)

return node

stack =

i, node, n = [0, 0, 1]

scale = len(s)

print('待檢驗序列為%s' % s)

# 初始化變數,stack為檢查序列用到的棧,i,node,n分別為待檢序列的角標、棧頂指標、下乙個入棧的元素

# scale為變數變化的範圍,因為待檢序列、棧深、入棧元素的所在區間長度都一致

while((0

and n <= scale) or iif((node>0) and (stack[node - 1] == s[i])): # 若node大於0,表示棧中有元素,可以進行出棧操作

print('%d out' % stack[node-1])

pop(stack)

i += 1

node -= 1

elif(n <= scale): # 若n大於scale,表明待入棧元素已經全部進棧

push(n, stack)

print('%d in' % n)

n += 1

node += 1

else: # 兩種情況會退出迴圈:進棧佇列和棧中都為空時、棧不為空但棧頂元素與待檢序列不匹配時

break

if(node==0

and i==scale): # 若棧和進棧佇列均為空,則迴圈為正常退出,給定序列可以由棧得到

return

true

else: # 異常退出,給定序列不可由棧得到

return

false

defgets

(n):

# 生成待檢驗序列的函式,入參為序列中的最大整數n,返回乙個由整數1~n組成的序列s

from random import randint

s =

for i in range(n):

for i in range(n): # 將原本公升序排列的元素隨機兩兩交換n次

j = randint(0, n-1)

k = randint(0, n-1)

s[j], s[k] = s[k], s[j]

return s

s1 = [2, 5, 4, 3, 1]

s2 = [2, 5, 4, 1, 3]

s3 = gets(4)

s4 = gets(7)

checkstack(s1) # 返回true

checkstack(s2) # 返回false

checkstack(s3)

checkstack(s4)

給定基準重新排列鍊錶資料

leetcode練習題,比基準值小的放其前面,否則放後面,且原鍊錶的結點位置關係不變,如 8 2 5 1 6 3 4 9 10,給定基準值7 則結果為 2 5 1 6 3 4 8 9 10 建立兩個鍊錶,乙個放比基準值小的,乙個放大的,之後再將兩鍊錶鏈結起來即可 給定基準重新排列鍊錶資料 struc...

給定樹的後序和中序排列求先序排列

問題描述 給出一棵二叉樹的中序與後序排列。求出它的先序排列。約定樹結點用不同的大寫字母表示,長度 8 輸入格式 兩行,每行乙個字串,分別表示中序和後序排列 輸出格式 乙個字串,表示所求先序排列 樣例輸入 badc bdca 樣例輸出 abcd 演算法思想 我們先去尋找這棵樹的根,即後序排列的最後乙個...

給定字串,輸出由其中字元所有的組合,C

輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c所能排列出來的所有字串abc acb bac bca cab和cba。遞迴思想 假如針對abc的排列,可以分成 1 以a開頭,加上bc的排列 2 以b開頭,加上ac的排列 3 以c開頭,加上ab的排列 includ...