算法 | 求一个数组的所有子集

算法 | 求一个数组的所有子集

目录

一.例子

二.代码

三.分析

一.例子
现在有一个数组如下:

ar[3] = {1,2,3};
那么这个集合的全部子集为



} {1} {2} {3} {1,2} }{2,3} {1,3} {1,2,3}。

二.代码
#include<stdio.h>

void fun(int* ar, int* br, int i, int n)
{
if (i >= n)
{
for (int j = 0; j < n; ++j)
{
if (br[j])
{
printf("%d ", ar[j]);
}
}
printf("\n");
}
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;
}
三.分析


我们看到我们在这个数组的下标分别作了标记,其中:

0,0,0代表什么都不打印,即当前的子集为空集{ϕ

}
1,0,0代表打印1,即当前的子集为{1}
0,1,0代表打印2,即当前的子集为{2}
0,0,1代表打印3,即当前的子集为{3}
1,1,0代表打印1,2,即当前的子集为{1,2}
1,0,1代表打印1,3,即当前的子集为{1,3}
0,1,1代表打印2,3,即当前的子集为{2,3}
1,1,1代表打印1,2,3,即当前的子集为{1,2,3}
即当标记在数组下标的数字为1时,打印数组在这个位置的值。

我们将这一特性与一棵二叉树,相绑定,如下图所示

 

当第一次进入fun函数时,i = 0,n =3,i != n,此时执行br[i] = 1,fun(ar,br,i+1,n)
进入新的fun函数时,i = 1,n =3,i != n,此时执行br[i] = 1,fun(ar,br,i+1,n)
进入新的fun函数时,i = 2,n =3,i != n,此时执行br[i] = 1,fun(ar,br,i+1,n)
进入新的fun函数时,i = 3,n =3,i == n,此时执行打印语句
与此同时执行层次遍历,即执行b[i] = 0,fun(ar,br,i+1,n)
进入新的fun函数时,i = 3,n =3,i == n,此时执行打印语句
与此同时执行层次遍历,即执行b[i] = 0,fun(ar,br,i+1,n)
进入新的fun函数时,i = 2,n =3,i != n,此时执行br[i] = 1,fun(ar,br,i+1,n)
进入新的fun函数时,i = 3,n =3,i == n,此时执行打印语句
与此同时执行层次遍历,即执行b[i] = 0,fun(ar,br,i+1,n)
进入新的fun函数时,i = 3,n =3,i == n,此时执行打印语句
与此同时执行层次遍历,即执行b[i] = 0,fun(ar,br,i+1,n)
上面就是这个二叉树左子树的的执行过程,右面的执行过程与其相同,我们就不在进行阐述。
————————————————
版权声明:本文为CSDN博主「瘦弱的皮卡丘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ThinPikachu/article/details/105543798

 

posted @ 2023-09-19 19:00  菜鸡一枚  阅读(204)  评论(0)    收藏  举报