用图和栈的深度遍历思想解决组合全部序列的输出

例子:
有6个颜色各不相同的水桶,其桶身和桶盖颜色相同,现在将桶身和桶盖随机打乱组合,求全部桶盖和桶身都不匹配的组合有多少种?打印所有组合。

算法思想:
不同桶盖和桶身一对一匹配,但是颜色不能一样。我们建立一个列表:里面的元素值表示桶身元素的位置表示桶盖
我们对桶身进行遍历,假如桶身元素值等于它的这个位置,不能取;假如不等于而且以前没有被用过,它是可以用的,我们把它的值加到列表里面,列表的长度也加1.假如列表的长度变成水桶总数,输出目前列表里面的值。
删除元素的情况有两个:

  1. 现在的元素满了需要删除列表最后一个元素
  2. 现在的元素不能满足题目要求,组不了匹配序列,也删除列表最后一个元素。(不用担心删的不够,因为我们是递归调用,所以一层一层删回去直到满足条件)

我们采用图的深度遍历方法,设置访问矩阵表示桶身的使用情况。下面是所有代码可以运行,想来看解释的话在后面。

class ColorStack:
    color_list = []
    length = 0

    def __init__(self, length=0):
        self.length = length

    def push(self, x: int):
        self.color_list.append(x)
        self.length += 1

    def pop(self):
        if self.length <= 0:
            return -1
        var = self.color_list.pop()
        self.length -= 1
        return var


count = 0


def count_combinations():
    for i in range(6):
        color = ColorStack()
        visited_color = [0 for i in range(6)]
        if i != 0:
            visited_color[i] = 1
            color.push(i)
            DFS_color(color, visited_color)


def DFS_color(color=ColorStack(), visited_color=[]):
    for j in range(6):
        if color.length < 6:
            if visited_color[j] == 0 and (color.length - 1) != j:
                visited_color[j] = 1
                color.push(j)
                DFS_color(color, visited_color)
        if color.length == 6:
            print(color.color_list)
            global count
            count += 1
            break
    var = color.pop()
    visited_color[var] = 0


if __name__ == '__main__':
    count_combinations()
    print(count)

全部代码写完了,假如你想输出文字,在函数

def DFS_color(color=ColorStack(), visited_color=[]):

if color.length == 6:
    print(color.color_list)

变一下对映关系,元素的值表示桶身,顺序表示桶盖,color.color_list就是类似[1,2,3,4,5,0]这样的值

下面是解释————————————————————————
我们定义了一个类ColorStack用来存颜色种类,count表示组合的所有数量

def count_combinations():
    for i in range(6):
        color = ColorStack()
        visited_color = [0 for i in range(6)]
        if i != 0:
            visited_color[i] = 1
            color.push(i)
            DFS_color(color, visited_color)

元素的值表示桶身,顺序表示桶盖)我们想遍历所有的情况,for i in range(6) ,这个就表示让桶盖子匹配桶身,假如第一个桶盖子和桶身颜色不一样就能继续,第一个桶盖子有5种匹配的可能,这样就包含了所有序列。

def DFS_color(color=ColorStack(), visited_color=[]):
    for j in range(6):
        if color.length < 6:
            if visited_color[j] == 0 and (color.length - 1) != j: # 匹配成功
                visited_color[j] = 1
                color.push(j) # 进栈
                DFS_color(color, visited_color) # 遍历下一个桶盖子
        if color.length == 6:
            print(color.color_list)
            global count # 统计不同组合数量
            count += 1
            break
    var = color.pop() 
    visited_color[var] = 0

这个是深度遍历内部的详细过程,visited_color表示桶盖子的有没有匹配成功,1表示匹配成功,0表示没有匹配成功,假如现在color.length<6,表示没完全匹配完,需要继续匹配。

break

break是因为现在的序列已经满足,所以要跳出循环,因为你也没元素能用了

 var = color.pop() 
 visited_color[var] = 0

这里之所以放在for循环外面一方面是因为元素不能用了,另一方面假如你 j 变成 6了,在现有元素下你已经得不到符合要求的序列了,所以要出栈,让这个位置的桶盖重新变得能用,回退到上一层。
结果在下面:

D:\design_project\python_project\Scripts\python.exe D:/design_project/python_project/text.py
[1, 2, 0, 3, 4, 5]
[1, 2, 0, 4, 5, 3]
[1, 2, 0, 5, 4, 3]
[1, 2, 3, 0, 4, 5]
[1, 2, 3, 4, 0, 5]
[1, 2, 3, 4, 5, 0]
...

一共256种,有什么问题或者错误的地方大家可以互相交流一下。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为您提供一个基于邻接矩阵存储结构的带权无向深度遍历和广度遍历的算法实现。 首先,我假设您已经了解了邻接矩阵存储结构,即使用一个二维数组来表示中各个节点之间的边的关系和权值。 接下来,我们可以考虑使用递归的方式来进行深度遍历。具体步骤如下: 1. 从指定的起始节点开始遍历,将其标记为已访问。 2. 访问当前节点,并将其加入深度遍历序列中。 3. 对于当前节点的每个未访问的邻居节点,递归调用深度遍历函数。 4. 重复以上步骤,直到遍历完所有节点。 下面是一个基于邻接矩阵存储结构的深度遍历的实现代码: ```python def depth_first_traversal(graph, start, visited, traversal): visited[start] = True traversal.append(start) for i in range(len(graph)): if graph[start][i] != 0 and not visited[i]: depth_first_traversal(graph, i, visited, traversal) ``` 其中,graph是邻接矩阵存储的,start是遍历的起始节点,visited是一个布尔数组,用于标记节点是否已经被访问过,traversal是深度遍历序列。 接下来,我们可以考虑使用队列的方式来进行广度遍历。具体步骤如下: 1. 将起始节点加入队列,并标记为已访问。 2. 从队列中取出一个节点,并将其加入广度遍历序列中。 3. 对于当前节点的每个未访问的邻居节点,将其加入队列,并标记为已访问。 4. 重复以上步骤,直到队列为空。 下面是一个基于邻接矩阵存储结构的广度遍历的实现代码: ```python def breadth_first_traversal(graph, start): visited = [False] * len(graph) traversal = [] queue = [] queue.append(start) visited[start] = True while queue: current = queue.pop(0) traversal.append(current) for i in range(len(graph)): if graph[current][i] != 0 and not visited[i]: queue.append(i) visited[i] = True return traversal ``` 其中,graph是邻接矩阵存储的,start是遍历的起始节点,visited是一个布尔数组,用于标记节点是否已经被访问过,traversal是广度遍历序列。 希望这个算法实现可以帮助您完成对带权无向深度遍历和广度遍历

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值