核心思想:把求幂集元素的过程看作是在先序遍历一棵深度为n+1的满二叉树,从根节点开始,访问左孩子表示幂集元素(集合的子集)中不包含集合的第一个元素,访问右孩子表示幂集元素中包含集合的第一个元素,这样,在二叉树的第二层完成了对集合第一个元素的取舍,依次类推,当遍历到达第n+1层,也就是二叉树的叶子节点时,完成了集合所有元素的取舍,这时输出一个取舍后的幂集元素。满二叉树的第n+1层共有2n个叶子节点,代表了集合的2n个幂集元素,待遍历输出完整棵满二叉树的叶子节点,也就得到了我们要求的幂集。
C++代码实现过程:
template<class T> void Power(vector<vector<T>>& res,vector<T>& sumset,vector<T>& curset,int pos)//初始状态:res为空 curset为空 pos=0 { if(sumset.size()==0){return;} //递归条件 if(pos==sumset.size()) { res.push_back(curset); return; } //开始递归 //左子树递归==>取当前pos对应于sumset中的元素 curset.push_back(sumset[pos]); Power(res,sumset,curset,pos+1); //右子树递归==>不取当前pos对应于sumset中的元素 curset.pop_back();//上面插入过所以这时需要尾部删除 Power(res,sumset,curset,pos+1); }
主函数:(输出结果)
#include<bits/stdc++.h> using namespace std; //求幂级函数 template<class T> void Power(vector<vector<T>>& res,vector<T>& sumset,vector<T>& curset,int pos)//初始状态:res为空 curset为空 pos=0 { if(sumset.size()==0){return;} //递归条件 if(pos==sumset.size()) { res.push_back(curset); return; } //开始递归 //左子树递归==>取当前pos对应于sumset中的元素 curset.push_back(sumset[pos]); Power(res,sumset,curset,pos+1); //右子树递归==>不取当前pos对应于sumset中的元素 curset.pop_back();//上面插入过所以这时需要尾部删除 Power(res,sumset,curset,pos+1); } //输出幂集函数 template<class T> void Print(vector<vector<T> >& res) { int rsize=res.size(); for(int i=0;i<rsize;i++) { int csize=res[i].size(); if(csize==0) { cout<<"{}"<<" "; } else { cout<<"{"; for(int j=0;j<csize;j++) { if(j!=csize-1) { cout<<res[i][j]<<" "; } else { cout<<res[i][j]; } } cout<<"}"<<" "; } } cout<<endl; } //主函数 int main() { vector<int> sumset; for(int i=0;i<4;i++) { sumset.push_back(i+1); } vector<int> curset; vector<vector<int> > res; Power(res,sumset,curset,0); Print(res); system("pause"); return 0; }
运行结果: