有这样一个问题,比如说,让我们去求数列br={1,2,3}的所有子集。我们知道它的真子集有{1,2,3}、{1,2}、{1,3}、{2,3}、{1}、{2}、{3}、空集。一共八个。那我们怎么通过代码的方式实现它呢?
首先,我们来分析这样一个程序,如下:
int fun(int i, int n)
{
if (i >= n)
{
}
else
{
fun(++i, n);//一般不用后置加加,会无穷递归,栈溢出
fun(++i, n);
}
}
int main()
{
fun(0, 3);
}
如果我们把它与树的结构来展现,他会是什么样子呢?用层次分析法分析,如下图:
由上图我们可知,我们可以利用递归的方式来完成左右子树相关值的创建。那就进入正题,怎么求数列的一个子集呢。仔细观察这些子集,我们可以发现用数组来存放这些子集,数值与下标位置相对应,再用1表示有数字,0表示没有数字,展现结果如下:
再将此数组对应到树形结构上,左子树表示1,右子树表示0,就可以完全的表示出子集了。
由此,采用递归的方式我们可以写出代码如下:
void fun (int* ar, int* br, int i,int n)
{
if (i >= n)
{
for (int j = 0; j < n; ++j)
{
if (br[j])
{
cout << ar[j] << "";
}
}
cout << endl;
}
else
{
br[i] = 1;
fun(ar, br, i + 1, n);//左孩子
br[i] = 0;
fun(ar, br, i + 1, n);
}
}
int main()
{
int ar[] = { 1,2,3 };
int br[] = { 0,0,0 };
fun(ar, br, 0, 3);
return 0;
}
当到达最后一层i>=n的时候,就将排列树打印出来。之前都在依次按照左0右1的方式创建树。