在没有 C++ STL 容器的情况下实现集合
Set 是不同元素的集合。元素一旦添加就无法修改。有各种与集合相关的运算,例如并集、交集、幂集、笛卡尔积、集差、补集和相等。
设置方法:
- add(data) – 将“数据”添加到集合中
- unionSet(s) – 返回 set 与 set 's' 的并集
- 交叉集(s)–返回与集合's'的交集
- 补集(U)——返回集合的补集与通用集“U”
- 运算符-(s) – 返回 set 和 set 's' 的差异
- 运算符==(s) – 返回集合是否等于集合 's'
- displayProduct(s) – 打印 set 和 set 's' 的笛卡尔积到控制台
- displayPowerSet() – 将电源集打印到控制台
- toArray() – 将集合作为其元素的数组返回
- contains(s) – 返回集合是否包含元素 's'
- displaySet() – 将集合打印到控制台
- getSize() – 返回集合的大小
下面是一个使用二叉搜索树的集合的实现:
C++
// C++ implementation of the approach
#include
#include
#include
#include
#include
using namespace std;
// Structure to implement a node of a BST
template
struct Node {
// The data content of the node
T data;
// Link to the left child
Node* left;
// Link to the right child
Node* right;
public:
// Function to print the inorder
// traversal of the BST
void inorder(Node* r)
{
if (r == NULL) {
return;
}
inorder(r->left);
cout << r->data << " ";
inorder(r->right);
}
/*
Function to check if BST contains a node
with the given data
@param r pointer to the root node
@param d the data to search
@return 1 if the node is present else 0
*/
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);
}
/*
Function to insert a node with
given data into the BST
@param r pointer to the root node
@param d the data to insert
@return pointer to the root of the resultant BST
*/
Node* insert(Node* r, T d)
{
// Add the node when NULL node is encountered
if (r == NULL) {
Node* tmp = new Node;
tmp->data = d;
tmp->left = tmp->right = NULL;
return tmp;
}
// Traverse the left subtree if data
// is less than the current node
if (d < r->data) {
r->left = insert(r->left, d);
return r;
}
// Traverse the right subtree if data
// is greater than the current node
else if (d > r->data) {
r->right = insert(r->right, d);
return r;
}
else
return r;
}
};
// Class to implement a Set using BST
template
class Set {
// Pointer to the root of the
// BST storing the set data
Node* root;
// The number of elements in the set
int size;
public:
// Default constructor
Set()
{
root = NULL;
size = 0;
}
// Copy constructor
Set(const Set& s)
{
root = s.root;
size = s.size;
}
/*
Function to Add an element to the set
@param data the element to add to the set
*/
void add(const T data)
{
if (!root->containsNode(root, data)) {
root = root->insert(root, data);
size++;
}
}
/*
Function to compute the union of two sets
@param s set to find union with
@return the union set
*/
Set unionSet(Set& s)
{
Set res;
// Second set is returned
// if first set is empty
if (root == NULL)
return res;
// First set is returned
// if second set is empty
if (s.root == NULL)
return *this;
// The elements of the first set
// are added to the resultant set
stack*> nodeStack;
nodeStack.push(root);
// Preorder traversal of the BST
while (!nodeStack.empty()) {
Node* node;
node = nodeStack.top();
nodeStack.pop();
// The data is added to the resultant set
res.add(node->data);
if (node->right)
nodeStack.push(node->right);
if (node->left)
nodeStack.push(node->left);
}
// The elements of the second set
// are added to the resultant set
stack*> nodeStack1;
nodeStack1.push(s.root);
while (!nodeStack1.empty()) {
Node* 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;
}
/**
Computes the intersection of two sets
@param s the set to find intersection with
@return the intersection set
*/
Set intersectionSet(Set& s)
{
Set res;
stack*> nodeStack;
nodeStack.push(root);
while (!nodeStack.empty()) {
Node* 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;
}
/*
Function to compute the complement of the set
@param U the universal set
@return the complement set
*/
Set complementSet(Set& U)
{
return (U - *this);
}
/*
Function to compute the difference of two sets
@param s the set to be subtracted
@return the difference set
*/
Set operator-(Set& s)
{
Set res;
stack*> nodeStack;
nodeStack.push(this->root);
while (!nodeStack.empty()) {
Node* 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;
}
/*
Function that checks equality of two sets
@param s set to check equality with
@return boolean value denoting result of check
*/
bool operator==(Set& s)
{
if (s.getSize() != size) {
return false;
}
stack*> nodeStack;
nodeStack.push(this->root);
while (!nodeStack.empty()) {
Node* 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;
}
/*
Function to print the cartesian product of two sets
@param s the set to find product with
*/
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;
}
// Function to print power set of the set
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;
}
}
/*
Function to convert the set into an array
@return array of set elements
*/
T* toArray()
{
T* A = new T[size];
int i = 0;
stack*> nodeStack;
nodeStack.push(this->root);
while (!nodeStack.empty()) {
Node* 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;
}
/*
Function to check whether the set contains an element
@param data the element to search
@return relut of check
*/
bool contains(T data)
{
return root->containsNode(root, data) ? true : false;
}
// Function to print the contents of the set
void displaySet()
{
cout << "{ ";
root->inorder(root);
cout << "}" << endl;
}
/*
Function to return the current size of the Set
@return size of set
*/
int getSize()
{
return size;
}
};
// Driver code
int main()
{
// Create Set A
Set A;
// Add elements to Set A
A.add(1);
A.add(2);
A.add(3);
A.add(2);
// Display the contents of Set A
cout << "A = ";
A.displaySet();
cout << "P(A) = " << endl;
A.displayPowerSet();
// Check if Set A contains some elements
cout << "A " << (A.contains(3) ? "contains"
: "does not contain")
<< " 3" << endl;
cout << "A " << (A.contains(4) ? "contains"
: "does not contain")
<< " 4" << endl;
cout << endl;
// Create Set B
Set B;
// Insert elements to Set B
B.add(1);
B.add(2);
B.add(4);
// Display the contents of Set B
cout << "B = ";
B.displaySet();
cout << "P(B) = " << endl;
B.displayPowerSet();
cout << endl;
// Create Set C
Set C;
C.add(1);
C.add(2);
C.add(4);
// Display the contents of Set C
cout << "C = ";
C.displaySet();
cout << endl;
// Set F contains the difference
// of the Sets A and B
Set F = A - B;
cout << "A - B = ";
F.displaySet();
cout << endl;
// Set D contains the union
// of the Sets A and B
Set D = A.unionSet(B);
cout << "A union B = ";
D.displaySet();
cout << endl;
// Set E contains the intersection
// of the Sets A and B
Set E = A.intersectionSet(B);
cout << "A intersection B = ";
E.displaySet();
cout << endl;
// Display the product
cout << "A x B = ";
A.displayProduct(B);
cout << endl;
// Equality tests
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 U;
U.add(1);
U.add(2);
U.add(3);
U.add(4);
U.add(5);
U.add(6);
U.add(7);
// Complements of the respective Sets
Set A1 = A.complementSet(U);
Set B1 = B.complementSet(U);
Set C1 = C.complementSet(U);
cout << "A' = ";
A1.displaySet();
cout << "B' = ";
B1.displaySet();
cout << "C' = ";
C1.displaySet();
return 0;
}
输出:
A = { 1 2 3 }
P(A) =
{ }
{ 1 }
{ 2 }
{ 1 2 }
{ 3 }
{ 1 3 }
{ 2 3 }
{ 1 2 3 }
A contains 3
A does not contain 4
B = { 1 2 4 }
P(B) =
{ }
{ 1 }
{ 2 }
{ 1 2 }
{ 4 }
{ 1 4 }
{ 2 4 }
{ 1 2 4 }
C = { 1 2 4 }
A - B = { 3 }
A union B = { 1 2 3 4 }
A intersection B = { 1 2 }
A x B = { { 1 1 } { 1 2 } { 1 4 } { 2 1 } { 2 2 } { 2 4 } { 3 1 } { 3 2 } { 3 4 } }
Equality of Sets:
A != B
B = C
A != C
A' = { 4 5 6 7 }
B' = { 3 5 6 7 }
C' = { 3 5 6 7 }
可以使用 AVL 树或红黑树代替简单的 BST 使插入和搜索的最坏情况复杂度为 O(log(n))。
关于使用 STL set,请参考这篇文章 Set in C++ Standard Template Library (STL)。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。