巧用二叉树原理求解集合的幂集

巧用二叉树原理求解集合的幂集
 

         幂集是《离散数学》集合论中一个重要的概念,集合在《离散数学》中定义如下: 集合是一个元概念,它研究对象的全体,通常用大写字母表示集合。如集合A,集合B。集合的表示方式有两种,分别是例举法和描述法。

        如一个由大于1小于5的整数组成的集合,用例举法可以表示为:
设该集合为A,则 A={2,3,4 }
         用描述法可表示为:
设该集合为A,则A={x | 1<x<5 , x∈Z}
         集合的子集定义为:若对于一个集合B,它的所有元素都同时属于A,那么B是A的子集,特别的,如果一个集合没有任何元素,那么我们称它为空集,空集是任何集合的子集。同时,一个集合本身也是自己的子集。

         现在我们终于可以引出幂集的概念了,幂集被定义为:一个集合的所有子集组成的集合成为该集合的幂集。由此可见幂集是集合的集合。如集合A={1,2,3},那么它的幂集为P(A)={ {},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3} },一个有n个元素的集合,它的幂集有2 n个元素,这些元素都是该集合的子集。

         通过上面的简单介绍,我们看到,要求一个集合的幂集,在该集合所含元素较少时是可以很快看出的,但当集合元素增多时,幂集的元素则成几何级数增长,求集合的幂集变得非常困难。

         在这里,我编制了一个求集合幂集的程序,通过遍历一棵满二叉树,求解集合的幂集。程序的原理是:把求幂集元素的过程看作是在先序遍历一棵深度为n+1的满二叉树,从根节点开始,访问左孩子表示幂集元素(集合的子集)中不包含集合的第一个元素,访问右孩子表示幂集元素中包含集合的第一个元素,这样,在二叉树的第二层完成了对集合第一个元素的取舍,依次类推,当遍历到达第n+1层,也就是二叉树的叶子节点时,完成了集合所有元素的取舍,这时输出一个取舍后的幂集元素。满二叉树的第n+1层共有2 n个叶子节点,代表了集合的2 n个幂集元素,待遍历输出完整棵满二叉树的叶子节点,也就得到了我们要求的幂集。
         程序实现如下:
1    /*

2             code by: EricYou

3                date: 2006.1.7

4                blog: http://www.cnblogs.com/yxin1322 5

6     */

7

8    #include <stdio.h>

9    #include <string.h>

10

11    #define MAX_LENGTH 100 /*集合的最大元素个数*/

12

13    void PowerSet(char*, int, char*,int *);

14

15    int main()

16    {

17    	char a[MAX_LENGTH];		/*存储输入的集合*/

18    	char set[MAX_LENGTH]={"\0"};	/*储存集合的幂集元素*/

19    	int NumOfPowerSet=0;		/*幂集元素记数*/

20

21    	printf("Input the elements:");

22    	scanf("%s",a);

23

24    	printf("----------------------------\n");

25    	PowerSet(a,0,set,&NumOfPowerSet); /*调用递归函数*/

26    	printf("----------------------------\n");

27

28    	printf("Number of PowerSet: %d\n",NumOfPowerSet);

29

30    	return 1;

31    }

32

33    /*

34    	参数说明:	         char* a :	待求幂集的集合

35    			 int i :	当前分析到集合的第i个元素

36    		      char* set :	存储当前幂集元素状态

37    		       int* Num :	幂集元素记数

38    */

39    void PowerSet(char* a, int i, char* set, int * Num)

40    {

41    	char TempSet[MAX_LENGTH];

42

43    	strcpy(TempSet,set);

44    	if(i>=strlen(a))

45    	{

46    		printf("{%s}\n",set);

47    		(*Num)++;

48    	}

49    	else

50    	{

51    		PowerSet(a,i+1,TempSet,Num);

52    		strncat(TempSet,(a+i),1);

53    		PowerSet(a,i+1,TempSet,Num);

54    	}

55    }

     输入测试数据:ABCD,表示集合{A,B,C,D},得到输出数据如下:
Input the elements:ABCD
-------------------------
{}
{D}
{C}
{CD}
{B}
{BD}
{BC}
{BCD}
{A}
{AD}
{AC}
{ACD}
{AB}
{ABD}
{ABC}
{ABCD}
-------------------------
Number of PowerSet: 16

你可能感兴趣的:(二叉树)