全排列遞迴與非遞迴python實現

2021-08-24 20:42:47 字數 1920 閱讀 1305

全排列就是,給定乙個序列,列舉出該序列中元素所有的排列情況,列舉方法有遞迴和非遞迴兩種,詳細可以見這位大神寫的部落格:我只列出來兩個重要的圖吧。

1.非遞迴:字典序法 ,如下圖[1,2,3]的例子

2.遞迴方法

遞迴方法就是將序列中第一位固定,然後將後面n-1為的全排列列舉出來,取遍第一位所有取值,遞迴地得到所有排列。

python實現如下: 

# -*- coding:utf-8 -*-

# _author_ = xu_qn

# 全排列 分為兩種:遞迴與非遞迴

# 遞迴方法

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] # 交換回來,還原成原來的序列放置重複交換

# 非遞迴:字典序法

def is_not_reverse(list): # 判斷是否為倒敘list

for i in range(len(list)-1):

if list[i] < list[i+1]:

return true

return false

def find_first_min(list): # 從右到左是遞增的 只需要找到最右大於pi的數

for i in range(len(list)-1, 0, -1):

if list[i] > list[0]:

min_index = i

break

return min_index

def reverse_list(list,first,last):

while first < last:

if list[first] > list[last]:

list[first], list[last] = list[last], list[first]

first += 1

last -= 1

def dictionary_permutation(list):

while is_not_reverse(list):

for i in range(len(list) - 2, -1, -1):

if list[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)

if __name__ == "__main__":

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

#recursion_permutation(list, 0, len(list))

dictionary_permutation(list)

python非遞迴全排列

剛剛開始學習python,按照廖雪峰的 看的,當前看到了函式這一節。結合陣列操作,寫了個非遞迴的全排列生成。原理是插入法,也就是在乙個有n個元素的已有排列中,後加入的元素,依次在前,中,後的每乙個位置插入,生成n 1個新的全排列。因為python切割陣列或者字串,以及合併比較方便,所以,程式會節省很...

全排列的遞迴與非遞迴

全排列是乙個十分基礎的概念,是一串有可比權值的元素出現的所有排列形式,例如 張全蛋 張蛋全 全張蛋 全蛋 張 蛋全張 蛋張全 就是張全蛋的全排列,所以我們發現全排列用來取名字是很不錯的,如果對每個漢字在名字中的權值做一 張表,再來一張可能出現的不同字同時出現在名字中的關聯權值表,那麼全排列可以算出一...

全排列 遞迴與非遞迴實現

全排列問題在公司筆試的時候非經常見,這裡介紹其遞迴與非遞迴實現。簡單地說 就是第乙個數分別以後面的數進行交換 e.g e a b c 則 prem e a.perm b,c b.perm a,c c.perm a,b 然後a.perm b,c ab.perm c ac.perm b abc acb....