您的位置:首页 > 其它

利用二叉树先序遍历求含n个元素的集合的幂集(used stack and vector)

2014-04-18 22:28 399 查看
从集合A的每个元素来看,它只有两种状态:它或者属幂集的元素集,或不属幂集的元素集。则求幂集p(A)的元素的过程可看成是依次对集合A中元素进行取舍过程,并且可以用一棵二叉树(下图),来表示过程中幂集元素的状态变化过程。其中树中的根结点表示幂集元素的初始状态(为空集),叶子结点表示它的终结状态。

因此求幂集元素的过程即先序遍历这棵状态树的过程。所以可以用递归和非递归两种方法求解。

#include<iostream>
#include<stack>
#include<list>
#include<cmath>
#include<cctype>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<fstream>
#include<algorithm>
using namespace std;
void Print(vector<int> &v)
{
vector<int>::iterator it;
it=v.begin()+1;
if( it==v.end() )
{
cout<<"NULL\n";
return;
}
for(; it!=v.end(); it++)
cout<<*it<<" ";
cout<<endl;
}
//求集合A的幂集,递归算法
void GetPowerSet(int i, vector<int> &A, vector<int> &B)
{
if( i>A.size() ) Print(B);
else
{
int elem=A[i-1];
B.push_back(elem);//取集合A中的第i个元素
GetPowerSet(i+1,A,B);
B.pop_back();
//vector<int>::iterator iter=B.end()-1;
//B.erase(iter);//舍集合A中的第i个元素
GetPowerSet(i+1,A,B);
}
}
//求集合A的幂集,非递归算法
void GetPowerSet(const vector<int> &v)
{
int i, e;
/* 先序遍历(非递归) 思路:访问T->data后,将T入栈,遍历左子树;遍历完左子树返回时,栈顶元素应为T,出栈,再先序遍历T的右子树。 */
stack< vector<int> > s;
/*保存节点信息,这里节点信息是数组形式的,可以用向量存储每个节点的信息*/
vector<int> cur;
/*初始化时节点个数为0*/
cur.push_back(0);
s.push(cur);
while( !s.empty() )
{
/*只要没有到叶子节点就,遍历左子树因为这里叶子节点在第v.size() 层,所以直接判断cur是否到了叶子节点即可*/
while( cur[0]<v.size() )
{
i=cur[0];
e=v[i];
/*取第i个数保存到这个节点*/
cur.push_back(e);
/*取数的个数加1*/
cur[0]++;
/*把此节点放入栈,继续遍历左子树*/
s.push(cur);
cur=s.top();
}
/*到达叶子节点,这里保存的就是幂集的一个分支也就是叶子节点的值,访问该节点 退栈,返回节点的上一层*/
Print(cur);
s.pop();
if( !s.empty() )
{
/*访问右子树*/
cur=s.top();
s.pop();
/*cur[0]直接加1代表不要这个数也就是舍弃这个数然后这代表的就是该节点的值,存入栈中*/
cur[0]++;
s.push(cur);
}
}
}
int main(int argc, char *argv[])
{
vector<int> v, a;
v.push_back(1);
v.push_back(2);
v.push_back(3);
a.push_back(0);//表示根节点为空
GetPowerSet(1, v, a);
GetPowerSet(v);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: