堆算法的问题:并非所有排列都生成

Posted

技术标签:

【中文标题】堆算法的问题:并非所有排列都生成【英文标题】:Problem with Heap's algorithm: not all permutations are generated 【发布时间】:2021-11-23 08:24:12 【问题描述】:

我想使用 Heap 算法的递归版本来获得从 1 到 k 的自然数序列的所有排列,但遇到了一些困难。

对于 k = 3,程序输出 123、213、312、132,但由于某种原因,它没有考虑 231 和 321。更具体地说,根据执行 javascript 版本算法的视频 (https://www.youtube.com/watch?v=xghJNlMibX4),通过第五次排列,k 应该等于 3(在循环中改变)。我不明白为什么在我的情况下它达到 1,并且循环停止执行。

int i, n, temp;
int[] a;
string str = "";
private void button1_Click(object sender, EventArgs e)

    k = int.Parse(textBox1.Text);
    a = new int[k];
    for (i = 1; i <= k; i++)
        a[i - 1] = i;
    Generate(a, k);

private void Generate(int[] a, int k)

    if (k == 1)
    
        foreach (int digit in a)
            str += digit.ToString();
        listBox1.Items.Add(str);
        str = "";
        return;
    
    Generate(a, k - 1);
    for (i = 0; i < k - 1; i++)
    
        if (k % 2 == 1) Swap(a, 0, k - 1);
        else Swap(a, i, k - 1);
        Generate(a, k - 1);
    

public void Swap(int[] a, int i, int j)

    temp = a[i];
    a[i] = a[j];
    a[j] = temp;

我专注于在 Wiki 上找到的算法变体:https://en.wikipedia.org/wiki/Heap%27s_algorithm。有趣的是,我从这里得到的几乎相同的一个:https://www.geeksforgeeks.org/heaps-algorithm-for-generating-permutations/ 工作正常。

看起来我无法从表单的控制台应用程序正确重写它。 我可以尝试不使用递归的版本,但我仍然想找出我在构建递归算法时的错误。

【问题讨论】:

您是否对迭代进行了逐步调试以查看实际值是否符合您的预期? 是的,这就是为什么我发现在循环结束时 k = 3。很难比较两个代码的每一步,所以我最终放弃了它并尝试对整体情况。 【参考方案1】:

问题是你的循环变量i 是一个全局变量。这意味着当您在循环体内进行递归调用时,该递归将改变该循环变量的值。当递归从它开始的地方返回时,i 将不再具有相同的值,并且循环将提前退出。

所以改变:

    for (i = 0; i < k - 1; i++)

到:

    for (int i = 0; i < k - 1; i++)

最好避免使用全局变量,并在需要它们的地方以尽可能小的范围声明它们。

【讨论】:

我建议对int[] aint temp 也进行同样的处理。

以上是关于堆算法的问题:并非所有排列都生成的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的排列算法对所有排列都给出相同的结果?

无连续字母的排列数相同

HDU 6116 路径计数

是否有一种算法可以生成多重集的所有唯一循环排列?

C语言数字全排列的问题(急!!)求C代码和算法

算法:堆排序