列表/数组全排列-python

全排列


针对一个数组/列表进行全排列有两种方法,一种是切片的方法,一种是调换顺序

切片

切片的方法实际上和高中数学讲的是一样的,有一个n维列表/数组,第一个位置有n种选择,第二个有n-1中选择(不包括前一个第一个选中的数),依次类推。。。

def perm(data):
	if len(data) == 1:#和阶乘一样,需要有个结束条件
		return [data]
	r = []
	for i in range(len(data)):
		s = data[:i] + data[i+1:] #去掉第i个元素,进行下一次的递归
		p = perm(s)
		for x in p:
			r.append(data[i:i+1]+x) #一直进行累加
	return r
data = [1,2,3]
print(perm(data))		

这种方法便于理解

调换顺序

这种实际上遍历列表/数组中所有可能的顺序,并进行赋值

def perm(lis,begin,end): #调换顺序
    #print "调用perm函数"
    if begin>=end: #等到所有循环走完,直接进行输出
        print(lis)
    else:
        i = begin
        for num in range(begin,end):
            lis[num],lis[i] = lis[i],lis[num] #固定当前位置,在进行下一位的排列
            perm(lis,begin+1,end) #在这一步就可以输出结果       
            # 调用结束之后还需要回溯将交换位置的元素还原,以供其他下降路径使用(二叉树)
            lis[num],lis[i] = lis[i],lis[num]

输出

global stackB
stackB = [None] * 全排列个数
global top
top = -1
def push(data):
    global top  #如果没有这些,相当于其为局部变量
    # global stackB
    if top >= 全排列个数:
        print('堆栈已满,无法再加入')
    else:
        top += 1
        stackB[top] = data
        print('压栈数据:',data)

def perm(lis,begin,end): #调换顺序
    if begin >= end:
        push(copy.copy(lis))
        print(lis)
    else:
        i = begin
        for num in range(begin,end):
            lis[num],lis[i] = lis[i],lis[num] #固定当前位置,在进行下一位的排列
            perm(lis,begin+1,end)
            # 调用结束之后还需要回溯将交换位置的元素还原,以供其他下降路径使用(二叉树)
            lis[num],lis[i] = lis[i],lis[num]

stackA = list(range(1,n+1)) # 输入数据
perm(stackA,0,len(stackA))
print(stackB)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值