巧用二叉树原理求解集合的幂集
巧用二叉树原理求解集合的幂集
幂集是《离散数学》集合论中一个重要的概念,集合在《离散数学》中定义如下:集合是一个元概念,它研究对象的全体,通常用大写字母表示集合。如集合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