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

目录

一.例子

二.代码

三.分析


一.例子

现在有一个数组如下:

ar[3] = {1,2,3};

那么这个集合的全部子集为

{\phi} {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代表什么都不打印,即当前的子集为空集{\phi}
  • 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时,打印数组在这个位置的值。

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

扫描二维码关注公众号,回复: 11096187 查看本文章

  • 当第一次进入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)

上面就是这个二叉树左子树的的执行过程,右面的执行过程与其相同,我们就不在进行阐述。

发布了88 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ThinPikachu/article/details/105543798