巧用二叉树原理求解集合的幂集
2008-03-08 17:44
288 查看
巧用二叉树原理求解集合的幂集
[align=left][/align]
幂集是《离散数学》集合论中一个重要的概念,集合在《离散数学》中定义如下:集合是一个元概念,它研究对象的全体,通常用大写字母表示集合。如集合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个幂集元素,待遍历输出完整棵满二叉树的叶子节点,也就得到了我们要求的幂集。
程序实现如下:
[align=left][/align]
幂集是《离散数学》集合论中一个重要的概念,集合在《离散数学》中定义如下:集合是一个元概念,它研究对象的全体,通常用大写字母表示集合。如集合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
相关文章推荐
- 巧用二叉树原理求解集合的幂集
- 巧用二叉树原理求解集合的幂集
- 集合框架_TreeSet保证元素唯一性和自然排序的原理和图解(二叉树结构)
- 利用二叉树先序遍历求含n个元素的集合的幂集(used stack and vector)
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
- 先序中序求解二叉树(使用二叉查找树原理)
- JAVA 常用集合内部机制原理
- 第十一周 项目二【用二叉树求解代数表达式】
- 第11周 项目2-用二叉树求解代数表达式
- TreeSet集合排序原理
- 【深入理解java集合系列】LinkedHashMap实现原理
- 深入Java集合学习系列:Hashtable的实现原理
- Java集合----LinkedHashSet的实现原理
- 第十一周 项目2 用二叉树求解代数表达式
- 第十周项目2 - 用二叉树求解代数表达式
- 199. Binary Tree Right Side View | 从右边看二叉树得到的集合
- 递归求解二叉树的深度
- 【编译原理】First /Follow /FirstVt /LastVt 集合的简单学习
- 深入Java集合学习系列:LinkedHashSet的实现原理
- 深入Java集合学习系列:HashMap的实现原理