排列生成算法

排列生成算法
排列生成法探讨了排列的组织方式。
参考书目:《卢开澄-组合数学(2006)第四版》

学习目标:

  • Python代码实现字典序法、换位法

记录时间:

  • 2023.9.27

学习内容:

字典序法

思路

在这里插入图片描述
在这里插入图片描述

代码

def dict_generate(n):
    """
    使用字典序法生成 1-n的所有排列
    书p17
    """
    arr = []
    cnt = 1
    # 初始化为 1,2,...,n
    for i in range(n):
        arr.append(i+1)
    print(arr)
    while True:
        i=-1
        for j in range(1,n):
            if arr[j-1] < arr[j]:
                i = j
        if i==-1 : # 找不到这样的i,算法结束
            break
        h = -1
        for k in range(0,n):
            if arr[i-1] < arr[k]:
                h = k
        # 互换
        arr[h], arr[i-1] = arr[i-1], arr[h]

        # 逆置i之后的
        arr[i:] = arr[len(arr)-1:i-1:-1]
        print(arr)
        cnt += 1
    print(f"total:{cnt}")

换位法

思路

在这里插入图片描述

代码
def swap_generate(n):
    """
    使用换位法生成 1-n的所有排列
    书p18
    """
    arr = []
    cnt = 1
    # 生成初始箭头全往左的数组  -1 代表往左,  1 代表往右
    for i in range(n):
        arr.append([i+1, -1])
    print([arr[i][0] for i in range(n)] ) # 打印初始数组
    while True:
        next_index = -1
        m = -1  # 假设这是最小最小的值,因为1-n,最小也才1
        for i in range(n):  # 找到m
            direction =  arr[i][1]
            if i+direction < 0 or i+direction == n:
                continue
            if arr[i][0] > arr[i+direction][0]:
                if m < arr[i][0]:
                    m = arr[i][0]
                    next_index = i
        if next_index == -1: # 找不到处于活动状态的数了
            break
        # 互换
        direction =  arr[next_index][1]
        arr[next_index], arr[next_index + direction] = arr[next_index + direction], arr[next_index]
        # 改变比m大的所有数的方向
        for i in range(n):
            if arr[i][0] > m:
                arr[i][1] = -arr[i][1]
        print([arr[i][0] for i in range(n)] ) # 打印数组
        cnt += 1
    print(f"total:{cnt}")

在这里插入图片描述

改进

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
算法思路:
在这里插入图片描述
在这里插入图片描述

def swap_generate2(n):


学习小结:

提示:这里统计学习计划的总量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值