使用递归函数用来输出n个元素的所有子集(数据结构、算法与应用)
例如,三个元素的集合A = {a,b,c}的所有子集是:空集a,b,c,ab,ac,bc,abc,共八个
分析:
对于集合A中的每个元素,在其子集中都可能存在或者不存在,所以A的子集有23种。
可以设置一个变量IsExist,用来表示集合A中的某个元素是否存在于子集中,如果IsExist = 1,则表示存在,如果IsExist = 0,则表示不存在
更近一步,可以想到设置一个数组IsExist[3],将数组IsExist与数组A中相同下标的元素绑定在一起。
例如如果IsExist = {0,0,0},则A对应的子集为空集
如果IsExist = {1,1,1},则A对应的子集为全集
所以我们表面上是在求一个子集问题,实际上是在求一个关于IsExist的全排列问题,如图
完全就是高中知识吧,现在的问题就变成了怎样求出这8个排列,肯定是用一个递归函数来求的
也很容易想到,这个函数至少需要两个参数
void Func(int Arr(),int Index){}
Arr()是用来记录排列结果的,Index用来记录当前处理的数组元素的下标
我们先从下标为0的元素开始处理,Arr(0)有两种情况,分别为0和1,两种情况下又对应着下标为1的情况,接着又对应着下标为2的情况,此时递归就结束了,即递归的终点标志是当Index等于Arr()的末尾元素的下标时,故我们联想到此函数还需要一个参数用来记录Arr()的长度,我们命名为Len,所以递归函数的完整代码是:
1 void Func(int Arr[], int Index, int Len)
2 {
3 if (Index == Len)
4 {
5 for (int i = 0; i < Len; i++)
6 {
7 cout << Arr[i];
8 }
9 cout << endl;
10 }
11 else
12 {
13 Arr[Index] = 0;
14 Func(Arr, Index + 1, Len);
15 Arr[Index] = 1;
16 Func(Arr, Index + 1, Len);
17 }
18 }
主函数为
1 int main()
2 {
3 int a[3];
4 Func(a, 0, 3);
5 system("pause");
6 }
写这个主函数主要是举个例子方便大家理解一下函数中参数的具体意义
在这个基础上写出集合的子集就很简单了,在函数里多加一个参数就行,具体代码如下:
1 #include<iostream>
2 using namespace std;
3 //n个元素的所有子集(递归函数)
4 template <typename T>
5 void Func(T Group[],int Arr[], int Index, int Len)
6 {
7 if (Index == Len)
8 {
9 cout << "{";
10 for (int i = 0; i < Len; i++)
11 {
12 if (Arr[i] == 1)
13 {
14 cout << Group[i];
15 }
16 }
17 cout << "}" << endl;
18 }
19 else
20 {
21 Arr[Index] = 0;
22 Func(Group,Arr, Index + 1, Len);
23 Arr[Index] = 1;
24 Func(Group,Arr, Index + 1, Len);
25 }
26 }
27
28 int main()
29 {
30 char group[3] = { 'a', 'b', 'c' };
31 int a[3];
32 Func(group,a, 0, 3);
33 system("pause");
34 }