目录
2_用位向量实现集合(附实现代码☟)

集合是表示事物的最有效的数学工具之一。
集合是由元素(成员)组成的一个类。集合的成员可以是一个集合,也可以是一个原子。
同一个元素在一个集合中不能多次出现。
有时需要表示有重复元素的集合,这时允许同一个元素在集合中多次出现。这样的集合称为多重集合。
当集合中的原子具有线性序关系(或称全序关系)“<”时,称集合为有序集(全序集或线性序集)。“<”是集合的一个线性序,它有如下性质:
约定:其中大写字母表示一个集合,小写字母表示集合中的一个元素
位向量实现的集合结构Bitset定义
- typedef struct bitset *Set; /* 位向量集合指针类型 */
- typedef struct bitset {
- int setSize; /* 集合大小 */
- int arraySize; /* 位数组大小 */
- unsigned short* v; /* 位数组 */
- }Bitset;
创建一个用位向量实现、可存储集合大小为size的空集
- Set SetInit(int size)
- {
- Set S = (Set)malloc(sizeof * S);
- S->setSize = size;
-
- /* 存储大小为setsize的集合所需的无符号短整数位数 */
- S->arraySize = (size + 15) >> 4;
- S->v = (unsigned short*)malloc(size * sizeof(unsigned short));
-
- /* 初始化为空集 */
- for (int i = 0; i < size; i++) S->v[i] = 0;
-
- return S;
- }
通过复制表示集合的位向量来实现赋值运算
- void SetAssign(Set A, Set B)
- {
- /* 集合赋值运算 */
- if (A->arraySize != B->arraySize) return;
- for (int i = 0; i < A->arraySize; i++) A->v[i] = B->v[i];
- }
通过检测元素在表示集合的位向量中相应的位来判断成员的属性
- int SetMember(int x, Set S)
- {
- /* 成员属性判断 */
- if (x < 0 || x > S->setSize) return 0;
- return S->v[ArrayIndex(x)] & BitMask(x);
- }
下标定位函数
- int ArrayIndex(int x)
- {
- /* 右移4位获得x在数组中的位置*/
- return x >> 4;
- }
- /* 位屏蔽函数*/
- unsigned short BitMask(int x)
- {
- /* 确定x在相应数组单元中的准确位置 */
- return 1 << (x & 15);
- }
-
- /* 判断集合相等函数 */
- int SetEqual(Set A, Set B)
- {
- /* 判断集合A和集合B是否相等*/
- if (A->arraySize != B->arraySize) return 0;
- int retval = 1;
- for(int i = 0; i < A->arraySize; i ++ )
- if (A->v[i] != B->v[i]) {
- retval = 0;
- break;
- }
- return retval;
- }
-
- /* 并集运算 */
- Set SetUnion(Set A, Set B)
- {
- Set tmp = SetInit(A->setSize);
- for (int i = 0; i < A->arraySize; i++)
- tmp->v[i] = A->v[i] | B->v[i];
- return tmp;
- }
-
- /* 交集运算 */
- Set SetIntersection(Set A, Set B)
- {
- Set tmp = SetInit(A->setSize);
- for (int i = 0; i < A->arraySize; i++)
- tmp->v[i] = A->v[i] & B->v[i];
- return tmp;
- }
-
- /* 差集运算 */
- Set SetDifference(Set A, Set B)
- {
- Set tmp = SetInit(A->setSize);
- for (int i = 0; i < A->arraySize; i++)
- tmp->v[i] = A->v[i] ^ B->v[i];
- return tmp;
- }
-
- /* 元素插入运算 */
- void SetInsert(int x, Set S)
- {
- if (x < 0 || x >= S->setSize) return;
- S->v[ArrayIndex(x)] |= ~BitMask(x);
- }
-
- /* 元素删除运算 */
- void SetInsert(int x, Set S)
- {
- if (x < 0 || x >= S->setSize) return;
- S->v[ArrayIndex(x)] &= ~BitMask(x);
- }