遞迴就是乙個自我呼叫的函式,不必深究,只需理解。只需要弄懂其中乙個過程就好,其他的過程都是一樣的,不必全部弄懂
下面講全排列的遞迴演算法
分三個階段:
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大的數中...