#include <algorithm>
#include <iostream>
#include <math.h>
#include <stack>
#include <string>
using
namespace
std;
template
<
typename
T>
struct
Node {
T data;
Node* left;
Node* right;
public
:
void
inorder(Node* r)
{
if
(r == NULL) {
return
;
}
inorder(r->left);
cout << r->data <<
" "
;
inorder(r->right);
}
int
containsNode(Node* r, T d)
{
if
(r == NULL) {
return
0;
}
int
x = r->data == d ? 1 : 0;
return
x | containsNode(r->left, d) | containsNode(r->right, d);
}
Node* insert(Node* r, T d)
{
if
(r == NULL) {
Node<T>* tmp =
new
Node<T>;
tmp->data = d;
tmp->left = tmp->right = NULL;
return
tmp;
}
if
(d < r->data) {
r->left = insert(r->left, d);
return
r;
}
else
if
(d > r->data) {
r->right = insert(r->right, d);
return
r;
}
else
return
r;
}
};
template
<
typename
T>
class
Set {
Node<T>* root;
int
size;
public
:
Set()
{
root = NULL;
size = 0;
}
Set(
const
Set& s)
{
root = s.root;
size = s.size;
}
void
add(
const
T data)
{
if
(!root->containsNode(root, data)) {
root = root->insert(root, data);
size++;
}
}
Set unionSet(Set& s)
{
Set<T> res;
if
(root == NULL)
return
res;
if
(s.root == NULL)
return
*
this
;
stack<Node<T>*> nodeStack;
nodeStack.push(root);
while
(!nodeStack.empty()) {
Node<T>* node;
node = nodeStack.top();
nodeStack.pop();
res.add(node->data);
if
(node->right)
nodeStack.push(node->right);
if
(node->left)
nodeStack.push(node->left);
}
stack<Node<T>*> nodeStack1;
nodeStack1.push(s.root);
while
(!nodeStack1.empty()) {
Node<T>* node;
node = nodeStack1.top();
nodeStack1.pop();
res.add(node->data);
if
(node->right)
nodeStack1.push(node->right);
if
(node->left)
nodeStack1.push(node->left);
}
return
res;
}
Set intersectionSet(Set& s)
{
Set<T> res;
stack<Node<T>*> nodeStack;
nodeStack.push(root);
while
(!nodeStack.empty()) {
Node<T>* node;
node = nodeStack.top();
nodeStack.pop();
if
(s.contains(node->data)) {
res.add(node->data);
}
if
(node->right)
nodeStack.push(node->right);
if
(node->left)
nodeStack.push(node->left);
}
return
res;
}
Set complementSet(Set& U)
{
return
(U - *
this
);
}
Set operator-(Set& s)
{
Set<T> res;
stack<Node<T>*> nodeStack;
nodeStack.push(
this
->root);
while
(!nodeStack.empty()) {
Node<T>* node;
node = nodeStack.top();
nodeStack.pop();
if
(!s.contains(node->data)) {
res.add(node->data);
}
if
(node->right)
nodeStack.push(node->right);
if
(node->left)
nodeStack.push(node->left);
}
return
res;
}
bool
operator==(Set& s)
{
if
(s.getSize() != size) {
return
false
;
}
stack<Node<T>*> nodeStack;
nodeStack.push(
this
->root);
while
(!nodeStack.empty()) {
Node<T>* node;
node = nodeStack.top();
nodeStack.pop();
if
(!s.contains(node->data)) {
return
false
;
}
if
(node->right)
nodeStack.push(node->right);
if
(node->left)
nodeStack.push(node->left);
}
return
true
;
}
void
displayProduct(Set& s)
{
int
i, j, n2 = s.getSize();
T* A = toArray();
T* B = s.toArray();
i = 0;
cout <<
"{ "
;
for
(i = 0; i < size; i++) {
for
(j = 0; j < n2; j++) {
cout <<
"{ "
<< A[i] <<
" "
<< B[j] <<
" } "
;
}
}
cout <<
"}"
<< endl;
}
void
displayPowerSet()
{
int
n =
pow
(2, size);
T* A = toArray();
int
i;
while
(n-- > 0) {
cout <<
"{ "
;
for
(
int
i = 0; i < size; i++) {
if
((n & (1 << i)) == 0) {
cout << A[i] <<
" "
;
}
}
cout <<
"}"
<< endl;
}
}
T* toArray()
{
T* A =
new
T[size];
int
i = 0;
stack<Node<T>*> nodeStack;
nodeStack.push(
this
->root);
while
(!nodeStack.empty()) {
Node<T>* node;
node = nodeStack.top();
nodeStack.pop();
A[i++] = node->data;
if
(node->right)
nodeStack.push(node->right);
if
(node->left)
nodeStack.push(node->left);
}
return
A;
}
bool
contains(T data)
{
return
root->containsNode(root, data) ?
true
:
false
;
}
void
displaySet()
{
cout <<
"{ "
;
root->inorder(root);
cout <<
"}"
<< endl;
}
int
getSize()
{
return
size;
}
};
int
main()
{
Set<
int
> A;
A.add(1);
A.add(2);
A.add(3);
A.add(2);
cout <<
"A = "
;
A.displaySet();
cout <<
"P(A) = "
<< endl;
A.displayPowerSet();
cout <<
"A "
<< (A.contains(3) ?
"contains"
:
"does not contain"
)
<<
" 3"
<< endl;
cout <<
"A "
<< (A.contains(4) ?
"contains"
:
"does not contain"
)
<<
" 4"
<< endl;
cout << endl;
Set<
int
> B;
B.add(1);
B.add(2);
B.add(4);
cout <<
"B = "
;
B.displaySet();
cout <<
"P(B) = "
<< endl;
B.displayPowerSet();
cout << endl;
Set<
int
> C;
C.add(1);
C.add(2);
C.add(4);
cout <<
"C = "
;
C.displaySet();
cout << endl;
Set<
int
> F = A - B;
cout <<
"A - B = "
;
F.displaySet();
cout << endl;
Set<
int
> D = A.unionSet(B);
cout <<
"A union B = "
;
D.displaySet();
cout << endl;
Set<
int
> E = A.intersectionSet(B);
cout <<
"A intersection B = "
;
E.displaySet();
cout << endl;
cout <<
"A x B = "
;
A.displayProduct(B);
cout << endl;
cout <<
"Equality of Sets:"
<< endl;
cout <<
"A "
<< ((A == B) ?
""
:
"!"
) <<
"= B"
<< endl;
cout <<
"B "
<< ((B == C) ?
""
:
"!"
) <<
"= C"
<< endl;
cout <<
"A "
<< ((A == C) ?
""
:
"!"
) <<
"= C"
<< endl;
cout << endl;
Set<
int
> U;
U.add(1);
U.add(2);
U.add(3);
U.add(4);
U.add(5);
U.add(6);
U.add(7);
Set<
int
> A1 = A.complementSet(U);
Set<
int
> B1 = B.complementSet(U);
Set<
int
> C1 = C.complementSet(U);
cout <<
"A' = "
;
A1.displaySet();
cout <<
"B' = "
;
B1.displaySet();
cout <<
"C' = "
;
C1.displaySet();
return
0;
}