Вы можете выяснить, как ведет себя printList
, нарисовав дерево рекурсии. Каждый узел состоит из двух элементов: alist
и blist
. Корень имеет alist
с начальной последовательностью элементов, которые вы хотите переставить, и пустой blist
.
Каждый узел дерева имеет одну ветвь для каждого элемента этого узла alist
; вы переходите от узла «отца» к каждому из его «детей», выбирая элемент из папок alist
и:
- присвоение ребенку
alist
отца alist
минус этот элемент ;
- присвоение ребенку
blist
отца blist
плюс этот элемент , добавленный в его конец .
Листья имеют пустой alist
, и, поскольку, следуя различным путям от корня до листьев, вы должны выбирать элементы из alist
корня в разных порядках, blist
самих листьев содержат все перестановки корня alist
.
Например ([abc],[] == alist,blist
):
[abc],[]
/ | \
a/ b| \c
/ | \
[bc],[a] [ac],[b] [ab],[c]
/ \
b/ \c
/ \
[c],[ab] [b],[ac]
| |
c| |b
| |
[],[abc] [],[acb]
def printList(alist, blist=[]):
# if alist is empty, we are in a 'leaf' in the recursion tree;
# then blist contains one permutation; print it
if not len(alist): print ''.join(blist)
# ELSE, for each possible position in alist,
for i in range(len(alist)):
# move the element at that position from alist to the end of blist
blist.append(alist.pop(i))
# go to the 'children' node and do the printing job for its subtree
printList(alist, blist)
# then move back the element from the end of blist to its original
# position in alist, so we can continue with the for loop
# without altering alist
alist.insert(i, blist.pop())