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

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

         幂集是《离散数学》集合论中一个重要的概念,集合在《离散数学》中定义如下:集合是一个元概念,它研究对象的全体,通常用大写字母表示集合。如集合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个元素的集合,它的幂集有2n个元素,这些元素都是该集合的子集。

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

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

posted on 2008-03-08 17:44  EricYou  阅读(2231)  评论(0编辑  收藏  举报

导航