Heap 算法的问题:不是所有的排列都生成
Problem with Heap's algorithm: not all permutations are generated
我想使用 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. Interestingly, the almost identical one which I took from here: https://www.geeksforgeeks.org/heaps-algorithm-for-generating-permutations/ 工作正常。
看来我无法从表单的控制台应用程序正确重写它。
我可以尝试那个没有递归的版本,但我仍然想找出我在构建递归算法时的错误。
问题是你的循环变量i
是一个全局变量。这意味着当您在循环体内进行递归调用时,该递归将改变该循环变量的值。当递归从开始的地方返回时,i
将不再具有相同的值,循环将提前退出。
所以改变:
for (i = 0; i < k - 1; i++)
至:
for (int i = 0; i < k - 1; i++)
最好避免使用全局变量,并在需要的地方以尽可能小的范围声明它们。
我想使用 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. Interestingly, the almost identical one which I took from here: https://www.geeksforgeeks.org/heaps-algorithm-for-generating-permutations/ 工作正常。
看来我无法从表单的控制台应用程序正确重写它。 我可以尝试那个没有递归的版本,但我仍然想找出我在构建递归算法时的错误。
问题是你的循环变量i
是一个全局变量。这意味着当您在循环体内进行递归调用时,该递归将改变该循环变量的值。当递归从开始的地方返回时,i
将不再具有相同的值,循环将提前退出。
所以改变:
for (i = 0; i < k - 1; i++)
至:
for (int i = 0; i < k - 1; i++)
最好避免使用全局变量,并在需要的地方以尽可能小的范围声明它们。