散列表(1)-集合/用位向量实现集合

散列表(1)-集合/用位向量实现集合_第1张图片 目录

1_集合

1.1_集合的定义

1.2_集合的记号

1.3_定义在集合上的基本运算

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


散列表(1)-集合/用位向量实现集合_第2张图片

1_集合

1.1_集合的定义

集合是表示事物的最有效的数学工具之一。

集合是由元素(成员)组成的一个类。集合的成员可以是一个集合,也可以是一个原子。
同一个元素在一个集合中不能多次出现。
有时需要表示有重复元素的集合,这时允许同一个元素在集合中多次出现。这样的集合称为多重集合

1.2_集合的记号

当集合中的原子具有线性序关系(或称全序关系)“<”时,称集合为有序集(全序集或线性序集)。“<”是集合的一个线性序,它有如下性质:

  1. 若a,b是集合中任意两个原子,则a
  2. 若a,b和c是集合中的原子,且a
  • 将集合的元素称为记录,每个记录有多个项(或域)来表示元素的各种属性。
  • 通过键值可以唯一地确定集合中的一个元素。
  • 键只是元素记录中许多域中的一个。
  • 集合中元素的列举顺序是任意的,如{1,3}和{3,1}表示同一个集合。
  • 关于集合的最基本的运算是并、交、差运算。
  • 设A和B是两个集合。
  • 把他们所有的元素合并在一起组成的集合,叫做集合A与集合B的并集,记作A∪B,读作A并B。
  • 由所有属于集合A且属于集合B的元素所组成的集合,叫做集合A与集合B的交集,记作A∩B
  • 则所有属于A且不属于B的元素构成的集合,叫做集合A减集合B(或集合A与集合B之差),类似地,对于集合A、B,把集合{x∣x∈A,且x∉B}叫做A与B的差集。例如:
  • A={1,2,3},B={2,4},则A-B={1,3}。

1.3_定义在集合上的基本运算

约定:其中大写字母表示一个集合,小写字母表示集合中的一个元素

  • Set_Union(A, B):并集运算
  • Set_Intersection(A, B):交集运算
  • Set_Difference(A, B):差集运算
  • Set_Assign(A, B):赋值运算(将B的元素赋给A)
  • Set_Equal(A, B):判等运算
  • Set_Member(A, B):成员运算
  • Set_Insert(x, S):插入运算
  • Set_Delete(x, S):删除运算

2_用位向量实现集合

  • 位向量是一种每个元素都是二进制位(即0/1值)的数组

位向量实现的集合结构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);
}

你可能感兴趣的:(算法,数据结构,c++,散列表,C语言)