全排列 遞迴和字典序列法

2021-09-29 15:26:35 字數 3112 閱讀 9711

遞迴就是乙個自我呼叫的函式,不必深究,只需理解。只需要弄懂其中乙個過程就好,其他的過程都是一樣的,不必全部弄懂

下面講全排列的遞迴演算法

分三個階段:

def

recursion_permutation

(list

, first, last)

:if first >= last:

# 遞迴結束情況

print

(list

)for i in

range

(first, last)

:# first包含,last不包含

list

[i],

list

[first]

=list

[first]

,list

[i] recursion_permutation(

list

, first +

1, last)

list

[i],

list

[first]

=list

[first]

,list

[i]# 交換回來,還原成原來的序列放置重複交換

比如123

先將1與其他各個數字進行交換(包括1自己),然後對23進行全排列,這裡只詳細講解1與2進行交換之後對剩下的數字進行全排列

123------213 #1與2進行交換

交換後對剩下的數字13進行全排列(1先與自己交換得到結果213,然後交換回來還是213,;然後1與3進行交換,得到結果231,然後交換回來再交換回來得到123,根結點,整個過程類似於樹排列,之後進行下一次的迴圈)

-----這樣就可以進行接下來的遞迴

1與3進行交換,123—321

交換後對剩下的數字21進行全排列。。。。。

字典序法

開始從小到大排列

1)從排列的右端開始,找出第乙個比右邊數字小的數字的序號j(j從左端開始計算),即 j=max(右邊的數從右至左是遞增的,因此k是所有大於pj的數字中序號最大者)

3)對換pi,pk

4)再將pj+1…pk-1pkpk+1…pn倒轉得到排列p』=p1p2…pj-1pjpn…pk+1pkpk-1…pj+1,這就是排列p的下乙個排列。

當所有排列都找完時,此時數字串從大到小排列`

# 非遞迴:字典序法

defis_not_reverse

(list):

# 判斷是否為倒敘list

for i in

range

(len

(list)-

1):if

list

[i]<

list

[i +1]

:return

true

return

false

deffind_first_min

(list):

# 從右到左是遞增的 只需要找到最右大於pi的數

for i in

range

(len

(list)-

1,0,

-1):

iflist

[i]>

list[0

]:min_index = i

break

return min_index

defreverse_list

(list

, first, last)

:while first < last:

iflist

[first]

>

list

[last]

:list

[first]

,list

[last]

=list

[last]

,list

[first]

first +=

1 last -=

1def

dictionary_permutation

(list):

while is_not_reverse(

list):

for i in

range

(len

(list)-

2,-1

,-1)

:iflist

[i]<

list

[i +1]

:# 從左到右找到第乙個左邊小於右邊的數pi 座標i

j = find_first_min(

list

[i:]

)# 找到pi右邊數字中比pi大的最小數下標

list

[i],

list

[j + i]

=list

[j + i]

,list

[i]# 交換pi,pj,pj在原list的座標i+j

reverse_list(

list

, i +1,

len(

list)-

1)# 將pi後的list倒轉,變為公升序

print

(list

)break

#注意,逆轉之後本輪迴圈結束,應該重新開始

if __name__ ==

"__main__"

:list=[

1,2,

2,3]

dictionary_permutation(

list

)

結果的一部分:

字典序列法不需要考慮重複數字,因為它有嚴謹的大小順序

全排列 方法 全排列函式和遞迴和字典序

給你乙個字串,按字典序從小到大輸出這個字串的全排列 乙個由小寫字母組成的長度小於等於8的不含重複字元的字串 按字典序從小到大輸出這個字串的全排列 abcabc acbbac bcacab cbanext permutation函式 組合數學中經常用到排列,這裡介紹乙個計算序列全排列的函式 next ...

全排列之字典序法

1 對於輸入的字典序排列,反向查詢第一對滿足a j 2 仍舊反向查詢第乙個下標k,使得 a j 3 交換a j 和a k 4 翻轉a j 1 a end 此法能適應有重複元素的系列 如下 include include using namespace std int cmp const void a...

全排列演算法之字典序法

字典序演算法如下 設p是1 n的乙個全排列 p p1p2.pn p1p2.pj 1pjpj 1.pk 1pkpk 1.pn 1 從排列的右端開始,找出第乙個比右邊數字小的數字的序號j j從左端開始計算 即 j max index return index 在pj的右邊的數字中,找出所有比pj大的數中...