求集合的幂集,我总结了2种方法
1 这道题如果刚开始没有思路,可以考虑一下一个元素在不在子集中是有两种状态的,可以用什么表示呢?
如果用0表示不在,1表示在的话,就是01序列的2进制数。只需要遍历0-2的n次幂的二进制01序列就可以了
这个是我早期写的代码
/*求一个集合的全部子集
增广贤文
2006.5.9
*/
int a[]={1,2,3,4};
#include <stdio.h>
#include <math.h>
#define N sizeof a/sizeof a[0]
void change(int b[])
{
int *p=b;
for(p=b;p<=b+N;p++)
{
if(*p==0)
{
*p=1;
break;
}
else if(*p==1)
{
*p=0;
}
}
}
main()
{
int i;
int j;
int b[N-1];
for(i= 0;i<N;i++)
b[i]=0; /*初始化数组b[i]*/
printf("the original set is :/n");
printf("{");
for(i=0;i<N;i++)
{
printf("%d ",a[i]);
}
printf("}/n") ;
printf("/n");
printf("all the Subsets as follows:/n ") ;
for(j=0;j<pow(2,N);j++)
{
printf("{");
for(i=0;i<N;i++)
{
if(b[i]!=0)
printf("%d ",a[i]);
else
printf(" ");
}
printf("}/n");
change(b);
}
getch();
}
2.使用二叉树遍历的方式
//作者 :增广贤文
//时间:2006.9.23
//内容:运用二叉树求一个集合的幂集
//经过测试准确无误
#include <iostream>
using namespace std ;
typedef struct node
{
char data ;
struct node * next ;
}listnode , * list ;
void CreateList(list &A);//创建一个链表
void Output(list A);//打印一个链表
int ListLength(list A);//求一个链表的长度,返回链表的长度
void GetElem(list A , int i , char &x ) ;//求链表的第i个元素x
void ListInsert(list A , int i , char x);//在链表的第i个节点后插入元素
void ListDelete(list A ,int i , char x) ;//删除链表的第i个节点
void PowerSet(int i ,list A ,list B);//求链表A的幂集,链表B表示A幂集的一个元素
char x ;
int main()
{
list A ;
cout<<"请输入集合的元素 :" ;
CreateList(A);
list B;
B = new listnode ;
B->data = 0 ;
B->next = NULL ;
PowerSet(1,A,B);
putchar('/n');
system("PAUSE");
return 0 ;
}
void CreateList(list &A) //创建一个链表
{
char value ;
A = new listnode ;
A->next = NULL ;
A->data = 0 ;
list p = NULL ;
list q = NULL ;
while((value = getchar())!= '/n')
{
if(A->next == NULL)
{
p = new listnode ;
p->data = value ;
A->next = p ;
p->next = NULL ;
A->data++ ;
}
else
{
q = new listnode ;
q->data = value ;
p->next = q ;
p = q ;
A->data++ ;
}
}
if(p != NULL)
{
p->next = NULL ;
}
}
void Output(list A)//打印一个链表
{
if(ListLength(A) > 0)
{
list p ;
p = A->next ;
while( p != NULL)
{
cout<<p->data<<" ";
p = p->next ;
}
}
else
cout<<"空集";
}
int ListLength(list A)//求一个链表的长度,返回链表的长度
{
return (int)A->data ;
}
void GetElem(list A , int i , char &x ) //求链表的第i个元素x
{
list p = A ;
int num = 1 ;
while(num < i+1)
{
p = p->next ;
num++ ;
}
x = p->data;
}
void ListInsert(list A , int i , char x)// 将元素x插入,在链表第i个节点位置
{
list p = A ;
list q = new listnode ;
q->data = x ;
int num = 0 ; //头节点的编号是0
while(num < i-1)
{
p = p->next ;
num++ ;
}
q->next = p->next ;
p->next = q ;
A->data++;
}
void ListDelete(list A ,int i , char x) //删除链表的第i个节点
{
list p = A ;
int num = 1 ;
while(num < i)//循环的到的p是第i-1个节点
{
p = p->next ;
num++ ;
}
list q = p->next ;//q为第i个节点
p->next = q->next ;
delete q ;
A->data-- ;
}
void PowerSet(int i ,list A ,list B)//求链表A的幂集,链表B表示A幂集的一个元素
{
if(i > ListLength(A))
{
Output(B);
putchar('/n');
}
else
{
GetElem(A,i,x);
int k = ListLength(B);
ListInsert(B,k+1,x);
PowerSet(i+1,A,B);
ListDelete(B,k+1,x);
PowerSet(i+1,A,B);
}
}
这个算法在清华大学的数据结构上有详细的解释
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1287932